D:\>poly.py
(x - 1) * (x^2 + x + 1) = x^3 - 1

  1. 1 import ply.lex as lex # pip install ply
  2. 2 import ply.yacc as yacc
  3. 3
  4. 4 def parse(s):
  5. 5 t = {}
  6. 6 tokens = ('NUM', 'VAR'); t_NUM = r'\d+'; t_VAR = r'[x|X]'; literals = ['+', '-', '*', '^']
  7. 7 def t_error(t): t.lexer.skip(1)
  8. 8 precedence = (('left', '+', '-'), ('nonassoc', '*'), ('nonassoc', '^'))
  9. 9 def p_1(p):
  10. 10 '''poly : poly '+' term
  11. 11 | poly '-' term'''
  12. 12 if p[2] == '-': t[p[3]] = -t[p[3]]
  13. 13 def p_2(p): 'poly : term'
  14. 14 def p_3(p): "poly : '-' term"; t[p[2]] = -t[p[2]]
  15. 15 def p_4(p): 'term : NUM'; t[0] = int(p[1]); p[0] = 0;
  16. 16 def p_5(p): 'term : VAR'; t[1] = 1; p[0] = 1;
  17. 17 def p_6(p): "term : NUM '*' VAR"; t[1] = int(p[1]); p[0] = 1
  18. 18 def p_7(p): "term : VAR '^' NUM"; t[int(p[3])] = 1; p[0] = int(p[3])
  19. 19 def p_8(p): "term : NUM '*' VAR '^' NUM"; t[int(p[5])] = int(p[1]); p[0] = int(p[5])
  20. 20 def p_error(p): raise Exception()
  21. 21 lexer = lex.lex()
  22. 22 yacc.yacc().parse(s)
  23. 23 return t
  24. 24
  25. 25 class poly:
  26. 26 @staticmethod # e: exponent, c: coefficient
  27. 27 def canonical(d): return { e:c for e,c in d.items() if c }
  28. 28 def __init__(m, s): m.d = poly.canonical(parse(s) if isinstance(s, str) else s)
  29. 29 def __str__(m):
  30. 30 first = 1
  31. 31 s = ''
  32. 32 for e,c in sorted(m.d.items(), key=lambda ec:ec[0], reverse=1):
  33. 33 if first: s += '-' if c < 0 else ''
  34. 34 else: s += ' - ' if c < 0 else ' + '
  35. 35 c = abs(c)
  36. 36 if e == 0: s += str(c); continue
  37. 37 if c != 1: s += str(c) + '*'
  38. 38 s += 'x' if e == 1 else 'x^' + str(e)
  39. 39 first = 0
  40. 40 return s
  41. 41 def __mul__(a, b):
  42. 42 d = {}
  43. 43 for e,c in a.d.items():
  44. 44 for e2,c2 in b.d.items():
  45. 45 e3 = e + e2; d[e3] = d.get(e3, 0) + c * c2
  46. 46 return poly(d)
  47. 47 #print(poly('-x^4 - 3*x^2 - 2*x - 5'))
  48. 48 a = poly('x - 1'); b = poly('x^2 + x + 1')
  49. 49 print('(', a, ') * (', b, ') = ', a * b, sep='')

search(computer algebra), search(unexpected applications of polynomials in combinatorics), search(多项式算法 快速傅里叶变换FFT)

科学计算可分为数值计算和符号计算两类。MATLAB和SymPy好像两者都用上了。比如MATLAB能分解因式,好像会出来0.999999999999这样的系数,但多项式相乘的复杂度是优化前O(n*n),用上FFT后O(n*log(n))。

Created by PLY version 3.11 (http://www.dabeaz.com/ply) https://ply.readthedocs.io/en/latest/

Grammar

Rule 0 S' -> poly
Rule 1 poly -> poly + term
Rule 2 poly -> poly - term
Rule 3 poly -> term
Rule 4 poly -> - term
Rule 5 term -> NUM
Rule 6 term -> VAR
Rule 7 term -> NUM * VAR
Rule 8 term -> VAR ^ NUM
Rule 9 term -> NUM * VAR ^ NUM

Terminals, with rules where they appear

* : 7 9
+ : 1
- : 2 4
NUM : 5 7 8 9 9
VAR : 6 7 8 9
^ : 8 9
error :

Nonterminals, with rules where they appear

poly : 1 2 0
term : 1 2 3 4

Parsing method: LALR

state 0

(0) S' -> . poly
(1) poly -> . poly + term
(2) poly -> . poly - term
(3) poly -> . term
(4) poly -> . - term
(5) term -> . NUM
(6) term -> . VAR
(7) term -> . NUM * VAR
(8) term -> . VAR ^ NUM
(9) term -> . NUM * VAR ^ NUM

- shift and go to state 3
NUM shift and go to state 4
VAR shift and go to state 5

poly shift and go to state 1
term shift and go to state 2

state 1

(0) S' -> poly .
(1) poly -> poly . + term
(2) poly -> poly . - term

+ shift and go to state 6
- shift and go to state 7

state 2

(3) poly -> term .

+ reduce using rule 3 (poly -> term .)
- reduce using rule 3 (poly -> term .)
$end reduce using rule 3 (poly -> term .)

state 3

(4) poly -> - . term
(5) term -> . NUM
(6) term -> . VAR
(7) term -> . NUM * VAR
(8) term -> . VAR ^ NUM
(9) term -> . NUM * VAR ^ NUM

NUM shift and go to state 4
VAR shift and go to state 5

term shift and go to state 8

state 4

(5) term -> NUM .
(7) term -> NUM . * VAR
(9) term -> NUM . * VAR ^ NUM

+ reduce using rule 5 (term -> NUM .)
- reduce using rule 5 (term -> NUM .)
$end reduce using rule 5 (term -> NUM .)
* shift and go to state 9

state 5

(6) term -> VAR .
(8) term -> VAR . ^ NUM

+ reduce using rule 6 (term -> VAR .)
- reduce using rule 6 (term -> VAR .)
$end reduce using rule 6 (term -> VAR .)
^ shift and go to state 10

state 6

(1) poly -> poly + . term
(5) term -> . NUM
(6) term -> . VAR
(7) term -> . NUM * VAR
(8) term -> . VAR ^ NUM
(9) term -> . NUM * VAR ^ NUM

NUM shift and go to state 4
VAR shift and go to state 5

term shift and go to state 11

state 7

(2) poly -> poly - . term
(5) term -> . NUM
(6) term -> . VAR
(7) term -> . NUM * VAR
(8) term -> . VAR ^ NUM
(9) term -> . NUM * VAR ^ NUM

NUM shift and go to state 4
VAR shift and go to state 5

term shift and go to state 12

state 8

(4) poly -> - term .

+ reduce using rule 4 (poly -> - term .)
- reduce using rule 4 (poly -> - term .)
$end reduce using rule 4 (poly -> - term .)

state 9

(7) term -> NUM * . VAR
(9) term -> NUM * . VAR ^ NUM

VAR shift and go to state 13

state 10

(8) term -> VAR ^ . NUM

NUM shift and go to state 14

state 11

(1) poly -> poly + term .

+ reduce using rule 1 (poly -> poly + term .)
- reduce using rule 1 (poly -> poly + term .)
$end reduce using rule 1 (poly -> poly + term .)

state 12

(2) poly -> poly - term .

+ reduce using rule 2 (poly -> poly - term .)
- reduce using rule 2 (poly -> poly - term .)
$end reduce using rule 2 (poly -> poly - term .)

state 13

(7) term -> NUM * VAR .
(9) term -> NUM * VAR . ^ NUM

+ reduce using rule 7 (term -> NUM * VAR .)
- reduce using rule 7 (term -> NUM * VAR .)
$end reduce using rule 7 (term -> NUM * VAR .)
^ shift and go to state 15

state 14

(8) term -> VAR ^ NUM .

+ reduce using rule 8 (term -> VAR ^ NUM .)
- reduce using rule 8 (term -> VAR ^ NUM .)
$end reduce using rule 8 (term -> VAR ^ NUM .)

state 15

(9) term -> NUM * VAR ^ . NUM

NUM shift and go to state 16

state 16

(9) term -> NUM * VAR ^ NUM .

+ reduce using rule 9 (term -> NUM * VAR ^ NUM .)
- reduce using rule 9 (term -> NUM * VAR ^ NUM .)
$end reduce using rule 9 (term -> NUM * VAR ^ NUM .)

  1. 1 # parsetab.py
  2. 2 # This file is automatically generated. Do not edit.
  3. 3 # pylint: disable=W,C,R
  4. 4 _tabversion = '3.10'
  5. 5
  6. 6 _lr_method = 'LALR'
  7. 7
  8. 8 _lr_signature = "left+-nonassoc*nonassoc^NUM VARpoly : poly '+' term\n\t\t\t\t\t\t| poly '-' termpoly : termpoly : '-' termterm : NUMterm : VARterm : NUM '*' VARterm : VAR '^' NUMterm : NUM '*' VAR '^' NUM"
  9. 9
  10. 10 _lr_action_items = {'-':([0,1,2,4,5,8,11,12,13,14,16,],[3,7,-3,-5,-6,-4,-1,-2,-7,-8,-9,]),'NUM':([0,3,6,7,10,15,],[4,4,4,4,14,16,]),'VAR':([0,3,6,7,9,],[5,5,5,5,13,]),'$end':([1,2,4,5,8,11,12,13,14,16,],[0,-3,-5,-6,-4,-1,-2,-7,-8,-9,]),'+':([1,2,4,5,8,11,12,13,14,16,],[6,-3,-5,-6,-4,-1,-2,-7,-8,-9,]),'*':([4,],[9,]),'^':([5,13,],[10,15,]),}
  11. 11
  12. 12 _lr_action = {}
  13. 13 for _k, _v in _lr_action_items.items():
  14. 14 for _x,_y in zip(_v[0],_v[1]):
  15. 15 if not _x in _lr_action: _lr_action[_x] = {}
  16. 16 _lr_action[_x][_k] = _y
  17. 17 del _lr_action_items
  18. 18
  19. 19 _lr_goto_items = {'poly':([0,],[1,]),'term':([0,3,6,7,],[2,8,11,12,]),}
  20. 20
  21. 21 _lr_goto = {}
  22. 22 for _k, _v in _lr_goto_items.items():
  23. 23 for _x, _y in zip(_v[0], _v[1]):
  24. 24 if not _x in _lr_goto: _lr_goto[_x] = {}
  25. 25 _lr_goto[_x][_k] = _y
  26. 26 del _lr_goto_items
  27. 27 _lr_productions = [
  28. 28 ("S' -> poly","S'",1,None,None,None),
  29. 29 ('poly -> poly + term','poly',3,'p_1','poly.py',10),
  30. 30 ('poly -> poly - term','poly',3,'p_1','poly.py',11),
  31. 31 ('poly -> term','poly',1,'p_2','poly.py',14),
  32. 32 ('poly -> - term','poly',2,'p_3','poly.py',15),
  33. 33 ('term -> NUM','term',1,'p_4','poly.py',16),
  34. 34 ('term -> VAR','term',1,'p_5','poly.py',17),
  35. 35 ('term -> NUM * VAR','term',3,'p_6','poly.py',18),
  36. 36 ('term -> VAR ^ NUM','term',3,'p_7','poly.py',19),
  37. 37 ('term -> NUM * VAR ^ NUM','term',5,'p_8','poly.py',20),
  38. 38 ]

python写的多项式符号乘法的更多相关文章

  1. 作业1+2.四则运算(改进后完整版,用python写的)_064121陶源

    概述: 用一个星期加上五一的三天假期自学了python,在Mac系统上重新写出了四则运算的程序,编译器是PyCharm,相当于完成了作业2.d)"选一个你从来没有学过的编程语言,试一试实现基 ...

  2. 「懒惰的美德」我用 python 写了个自动生成给文档生成索引的脚本

    我用 python 写了一个自动生成索引的脚本 简介:为了刷算法题,建了一个 GitHub仓库:PiperLiu / ACMOI_Journey,记录自己的刷题轨迹,并总结一下方法.心得.想到一个需求 ...

  3. Python写各大聊天系统的屏蔽脏话功能原理

    Python写各大聊天系统的屏蔽脏话功能原理 突然想到一个视频里面弹幕被和谐的一满屏的*号觉得很有趣,然后就想用python来试试写写看,结果还真玩出了点效果,思路是首先你得有一个脏话存放的仓库好到时 ...

  4. python写红包的原理流程包含random,lambda其中的使用和见简单介绍

    Python写红包的原理流程 首先来说说要用到的知识点,第一个要说的是扩展包random,random模块一般用来生成一个随机数 今天要用到ramdom中unifrom的方法用于生成一个指定范围的随机 ...

  5. Python写地铁的到站的原理简易版

    Python地铁的到站流程及原理(个人理解) 今天坐地铁看着站牌就莫名的想如果用Python写其工作原理 是不是很简单就小试牛刀了下大佬们勿喷纯属小弟个人理解 首先来看看地铁上显示的站牌如下: 就想这 ...

  6. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  7. 读书笔记汇总 --- 用Python写网络爬虫

    本系列记录并分享:学习利用Python写网络爬虫的过程. 书目信息 Link 书名: 用Python写网络爬虫 作者: [澳]理查德 劳森(Richard Lawson) 原版名称: web scra ...

  8. Python写UTF8文件,UE、记事本打开依然乱码的问题

    Python写UTF8文件,UE.记事本打开依然乱码的问题 Leave a reply 现象:使用codecs打开文件,写入UTF-8文本,正常无错误.用vim打开正常,但记事本.UE等打开乱码. 原 ...

  9. python 写的http后台弱口令爆破工具

    今天来弄一个后台破解的Python小程序,哈哈,直接上代码吧,都有注释~~ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ...

随机推荐

  1. hdu 1171 Big Event in HDU(背包DP)

    题意: 杭电搬迁,有N种设备,每种设备有个价值V,数量M,要求将这些设备平分,使得平分后两边的总价值尽可能地相等. 输出两边各自的总价值. 思路: 背包DP后,P=所有的总价值/2,然后从P开始往两边 ...

  2. 力扣 - 剑指 Offer 58 - I. 翻转单词顺序

    题目 剑指 Offer 58 - I. 翻转单词顺序 思路1 假如题目要求我们翻转字符串,那么我们可以从末尾往前开始遍历每一个字符,同时将每一个字符添加到临时空间,最后输出临时空间的数据就完成翻转了, ...

  3. 用STM32定时器中断产生PWM控制步进电机

    控制步进电机可以使用PWM.定时器中断.延时,这里用的就是定时器中断来让它转动. 一.硬件部分1.使用的硬件板子用的是正点原子的STM32F103 mini板,驱动器是DM420(DM420驱动器资料 ...

  4. Kubernetes(k8s)部署redis-cluster集群

    Redis Cluster 提供了一种运行 Redis 安装的方法,其中数据 在多个 Redis 节点之间自动分片. Redis Cluster 还在分区期间提供了一定程度的可用性,这实际上是在某些节 ...

  5. Spark记录(二):Spark程序的生命周期

    本文以Spark执行模式中最常见的集群模式为例,详细的描述一下Spark程序的生命周期(YARN作为集群管理器). 1.集群节点初始化 集群刚初始化的时候,或者之前的Spark任务完成之后,此时集群中 ...

  6. ansible简介安装配置

    ansible简介 ansible是一款,自动化运维管理工具.顾名思义是用于批量去管理及安装服务及批量管理主机. ansible与saltstack对比 ansible优点:配置简单,部署容易除主管理 ...

  7. pyinstaller打包:AttributeError: module ‘win32ctypes.pywin32.win32api’ has no attribute ‘error’

    pyinstaller打包:AttributeError: module 'win32ctypes.pywin32.win32api' has no attribute 'error' 是因为pyin ...

  8. Java使用iText7生成PDF

    前言 我们之前使用js库html2canvas + jspdf实现html转PDF.图片,并下载(详情请戳:html页面转PDF.图片操作记录),大致原理是将页面塞到画布里,以图片的方式放到PDF中, ...

  9. go微服务框架Kratos笔记(七)使用jwt认证中间件

    引言 Json web token (JWT) 是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,特别适用于分布式站点的单点登录(SSO)场景.JWT的声明一般被用来在身份提供者和 ...

  10. [bzoj1079]着色方案

    由于最终的染色只与ci为几的个数有关,因此定义状态f[a][b][c][d][e][p]表示有a个ci=1,b个ci=2,--,有e个ci=5,上一次选择了ci=p的.状态的转移:发现p会让p-1少选 ...