import re # 正则
from collections import defaultdict # defaultdict
# 提取一元多项式(type: str)中的次数和系数并转化为字典 -> {次数:系数}
# 例如:'ax^b' -> {b: a}, '-cx^d' -> {d: -c}
# 注意!输入需要是类似这种形式:2x^3 + 1 或者 2x^3+1x^0,不能是 2*x**3 + 1 或者 2*x^3 + 1
def poly_to_dict(polynomial):
polynomial = polynomial.replace(' ', '')
dictionary = defaultdict(int)
positions = [0, *(idx for idx, val in enumerate(polynomial) if val == '+' or val == '-'), len(polynomial)]
# 一个多项式是由多个单项式组成
# 而每个单项式都有5个部分:符号 + 系数 + 元 + 脱字符 + 次数
# 所以匹配规则需要有5个部分,其中“符号,系数,元,次数”有用
pattern = '([\+-])?(\d+)?([a-z])?\^?(\d+)?'
for i in range(len(positions) - 1):
monomial = polynomial[positions[i]: positions[i+1]]
sign, coeff, var, power = re.match(pattern, monomial).groups()
# 不要学这种if,if-else写法,我只是为了图方便好看才这样写
if not sign : sign = '+'
if not coeff: coeff = '1' if var else '0'
if not power: power = '1' if var else '0'
dictionary[int(power)] += int(sign + coeff)
return dictionary
# (提取次数和系数后)将其进行简单的运算,比如将两个一元多项式相加
# 其实就是将两个字典中key相同的把value加起来
def add_of_poly(dict1, dict2):
dict3 = dict1.copy()
for k2, v2 in dict2.items():
dict3[k2] += v2
return {k3: dict3[k3] for k3 in sorted(dict3, reverse = True) if dict3[k3]}
# (提取次数和系数后)将其进行简单的运算,比如将两个一元多项式相乘
# 其实就是将两个字典中key加起来,并把value相乘
def mult_of_poly(dict1, dict2):
dict3 = defaultdict(int)
for k1, v1 in dict1.items():
for k2, v2 in dict2.items():
dict3[k1 + k2] += v1 * v2
return {k3: dict3[k3] for k3 in sorted(dict3, reverse = True) if dict3[k3]}
# 将字典形式的多项式按照次数从大到小的顺序打印出来
# 比如:-2x^3 + 5 或者 3x^6 - 2x + 4 这种形式
def print_poly(dictionary):
output = ''
for power, coeff in dictionary.items():
symbol = '+' if coeff > 0 else '-'
variable = 'x' if power != 0 else ''
caret, exponent = ('^', power) if power != 0 and power != 1 else ('', '')
# 5个组成部分
output += ' {} {}{}{}{}'.format(symbol, abs(coeff), variable, caret, exponent)
# 将最终输出再次修正一下
if output:
if output[3] == '1': output = output[:3] + output[4:]
print(output[3:] if output[1] == '+' else output[1] + output[3:])
else:
print(0)
# 这个函数用作测试,可以看到只要输入满足+ax^b这种形式,就可以正确地得出结果
# 尽管在数学角度看,输入的多项式中有些是不合理的
def test():
'''
>>> a = ' 2x^3 + x + 5 - 1x^0'
>>> b = '- 6x^2 - x - 2x -x + x - 5x^6 + 0 - 0x^3 '
>>> dict_a = poly_to_dict(a)
>>> dict_b = poly_to_dict(b)
>>> print_poly(add_of_poly(dict_a, dict_b))
-5x^6 + 2x^3 - 6x^2 - 2x + 4
>>> a = ''
>>> b = 'x'
>>> c = '-x'
>>> dict_a = poly_to_dict(a)
>>> dict_b = poly_to_dict(b)
>>> dict_c = poly_to_dict(c)
>>> print_poly(add_of_poly(dict_a, dict_b))
x
>>> print_poly(add_of_poly(dict_a, dict_c))
-x
>>> print_poly(add_of_poly(dict_b, dict_c))
0
>>> print_poly(mult_of_poly(dict_a, dict_a))
0
>>> print_poly(mult_of_poly(dict_a, dict_b))
0
>>> print_poly(mult_of_poly(dict_a, dict_c))
0
>>> print_poly(mult_of_poly(dict_b, dict_a))
0
>>> print_poly(mult_of_poly(dict_b, dict_b))
x^2
>>> print_poly(mult_of_poly(dict_b, dict_c))
-x^2
>>> print_poly(mult_of_poly(dict_c, dict_a))
0
>>> print_poly(mult_of_poly(dict_c, dict_b))
-x^2
>>> print_poly(mult_of_poly(dict_c, dict_c))
x^2
'''
# 引入doctest进行测试
if __name__ == '__main__':
import doctest
doctest.testmod()