關鍵字
多項式乘法 卷積乘法 Python 多項式係數 卷積係數 複數多項式 華爲機考 算法
問題來源
來源於一個華爲面試題。題目內容大致如下:
題目描述
多項式 的係數[b(2) b(1) b(0)]=[1 2 5]
二者相乘所得的多項式 的係數[c(3) c(2) c(1) c(0)]=[1 3 7 5]
利用上面的計算方法,我們很容易得到:
c(0)=a(0)b(0)
c(1)=a(0)b(1)+a(1)b(0)
c(2)=a(0)b(2)+a(1)b(1)+a(2)b(0)
c(3)=a(0)b(3)+a(1)b(2)+a(2)b(1)+a(3)b(0)
其中:a(3)=a(2)=b(3)=0
在上面的基礎上推廣一下:
假定兩個多項式的係數分別爲a(n),n=0n1和b(n),n=0n2,這兩個多項式相乘所得的多項式係數爲c(n),則:
c(0)=a(0)b(0)
c(1)=a(0)b(1)+a(1)b(0)
c(2)=a(0)b(2)+a(1)b(1)+a(2)b(0)
c(3)=a(0)b(3)+a(1)b(2)+a(2)b(1)+a(3)b(0)
c(4)=a(0)b(4)+a(1)b(3)+a(2)b(2)+a(3)b(1)+a(4)b(0)
以此類推可以得到卷積算法:
上面這個式子就是a(n)和b(n)的卷積表達式。
通常我們把a(n)和b(n)的卷積記爲:a(n)b(n),其中的表示卷積運算符
輸入描述
兩個最高階數爲4的複數多項式係數序列。高階係數先輸入;每個係數爲複數,複數先輸入實數部分,再輸入虛數部分; 實部或者虛部爲0,則輸入爲0;
每個實部和虛部的係數最大值不超過1000
輸出描述
求卷積多項式係數輸出;先輸出高階係數,多項式算法.
輸出的期望結果是多項式乘積結果,因爲自己的算法研究的不太深入,所以膚淺地瞭解到這個可以稱之爲卷積。
測試Demo
輸入:
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
輸出
0
2
0
4
0
6
0
8
0
10
0
8
0
6
0
4
0
2
思路和代碼
方法一(數學邏輯)
思路:
利用純數學邏輯,兩個多項式相乘,是兩個多項式的每個係數和另一個多項式的係數循環遍歷相乘,並將次數相同的係數合併。
代碼:
import time
# 定義兩個多階多項式的階數,即每個多項式的最高次冪
# 因爲冪次的變化,決定終端輸入係數的個數。 此處也可以使用配置文件操作。
A_LEVEL = 4
B_LEVEL = 4
def get_plural_product(sub_as, sub_bs, an, bn):
"""
計算兩個複數乘積,返回乘積結果的冪次,以及結果的實部和虛部的係數。
:param sub_as: 列表,第一個複數的兩個係數
:param sub_bs: 列表,第二個複數的兩個係數
:param an: 第一個複數帶上的參數的冪次
:param bn: 第二個複數帶上的參數的冪次
:return: 列表,0元素爲結果值的冪次,1元素爲實數部分結果,2元素爲虛數部分結果
"""
return [an+bn, (sub_as[0] * sub_bs[0] - sub_as[1] * sub_bs[1]),
(sub_as[0] * sub_bs[1] + sub_as[1] * sub_bs[0])]
def update_plural_list(arr_mul, add_one):
"""
將兩個複數的乘積係數,添加到結果列表中。
:param arr_mul: 結果列表,是列表型列表。列表中包含 (A_LEVEL + B_LEVEL + 1)
個子列表; 子列表的格式大概是[n, a, b]形式,n代表次數,a代表n
冪次的實部係數,b代表n冪次的虛部係數。
:param add_one: 遍歷過程或得的臨時的兩個複數乘積的結果,結果也是[n, a, b]形式
:return: 更新的結果列表,將arr_mul中子列表的同add_one冪次相同的參數進行了相加操作。
"""
for a in arr_mul:
if a[0] == add_one[0]:
a[1] += add_one[1]
a[2] += add_one[2]
break
# 這裏的另外一個優化的方式是可以使用字典進行尋值。
def get_multi_product(arr_a, arr_b):
"""
獲取複數多項式的乘積
:param arr_a: 第一個複數多項式的係數列表,列表格式爲
[最高次實部,最高次虛部,次高次實部,次高次虛部, ......, 0次實部,0次虛部]
:param arr_b: 第二個複數多項式列表
:return: 無,按照從高次冪到低次冪,從實部到虛部順序打印結果係數。
"""
global A_LEVEL
global B_LEVEL
# 獲取結果最高次冪數
top_level = A_LEVEL + B_LEVEL
# 創建初始結果列表,格式應該爲:
# [[n, 0, 0], [n-1, 0, 0], [n-2, 0, 0], ..., [0, 0, 0]]
# 其中 n = (A_LEVEL + B_LEVEL), 最高次冪數。
# 子列表的 0索引位置爲冪次。1索引位置爲當前冪次的實數係數,2索引位置爲虛數係數。
res_arr = list()
for i in range(top_level+1)[::-1]:
res_arr.append([i, 0, 0])
# print("初始結果列表爲: {}".format(res_arr))
# 初始結果格式爲: [[n, 0, 0], [n-1, 0, 0], [n-2, 0, 0], ..., [0, 0, 0]]
# 將原始係數列表從最高次冪到最低次冪,從實部到虛部格式的一維繫數列表轉換爲二位列表
# 即: 將 [an, ani, ..., a0, a0i] 轉換爲: [[an, ani], ..., [a0, a0i]]
# 轉換爲列表型列表。子列表對應每個冪次的實數和虛數部分的係數。
arr_a_new = [arr_a[i:i+2] for i in range(0, len(arr_a), 2)]
arr_b_new = [arr_b[i:i+2] for i in range(0, len(arr_b), 2)]
print("更新多項式一系數結果列表: {}".format(arr_a_new))
print("更新多項式二係數結果列表: {}".format(arr_b_new))
for i in range(len(arr_a_new)):
for j in range(len(arr_b_new)):
res = get_plural_product(
arr_a_new[i], arr_b_new[j],
len(arr_a_new)-1-i, len(arr_b_new)-1-j)
update_plural_list(res_arr, res)
for ra in res_arr:
print(ra[1])
print(ra[2])
def main():
""" Main function """
global A_LEVEL
global B_LEVEL
# 定義兩個多項式的係數列表
a_arr = list()
b_arr = list()
# 從終端輸入兩個多項式的係數,並添加到對應的列表中
# 注意係數的輸入原則:
# 先輸入第一個多項式的所有係數,再輸入第二個多項式的所有係數
# 係數的次數從最高次到最低次, 係數先輸入實數部分,再輸入虛數部分
for i in range((A_LEVEL+1) * 2):
a_arr.append(int(input()))
for i in range((B_LEVEL+1) * 2):
b_arr.append(int(input()))
start_t = time.time()
# 調用函數,打印結果
get_multi_product(a_arr, b_arr)
print("數據處理消耗時間: {}".format(time.time() - start_t))
print("Done!!")
if __name__ == "__main__":
main()
方法二(算法邏輯)
思路:
利用卷積算法原理,結果中的n冪次係數爲兩個多項式中的x冪次和y冪次的乘積,其中:x+y=n.
代碼:
參考:
第二題 多項式卷積乘法
在代碼的基礎上做了些註釋和簡單修改。
import time
A_LEVEL = 4
B_LEVEL = 4
def juanji():
"""
輸入兩個多階項式的實部和虛部的係數,從高次到低次,從實部到虛數順序輸入
:return: 打印兩個多階多項式卷積結果係數。順序同輸入規則。
"""
global A_LEVEL
global B_LEVEL
# 初始化兩個多項式的係數列表
a_xishu = list()
b_xishu = list()
for i in range(A_LEVEL+1):
one = list()
one.append(int(input()))
one.append(int(input()))
a_xishu.append(one)
for i in range(B_LEVEL+1):
two = list()
two.append(int(input()))
two.append(int(input()))
b_xishu.append(two)
# 這個轉換很重要,利用了冪次和列表索引的聯繫,通過逆序轉換,冪次和列表索引一致
a_xishu = a_xishu[::-1]
b_xishu = b_xishu[::-1]
star_t = time.time()
a_len = len(a_xishu)
b_len = len(b_xishu)
top_level = A_LEVEL + B_LEVEL
for i in range(top_level+1)[::-1]:
ci_s = 0
ci_x = 0
for index in range(i + 1)[::-1]:
if i - index < a_len and index < b_len:
temp = fushumulity(a_xishu[i - index], b_xishu[index])
ci_s += temp[0]
ci_x += temp[1]
print(ci_s)
print(ci_x)
print("數據處理耗時: {}".format(time.time()-star_t))
def fushumulity(x, y):
s = x[0] * y[0] - x[1] * y[1]
x = x[0] * y[1] + x[1] * y[0]
return s, x
juanji()
聯繫我
如果有什麼疑問,可以聯繫探討![email protected]