描述
矩阵乘法的运算量与矩阵乘法的顺序强相关。
例如:
A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵
计算ABC有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。
编写程序计算不同的计算顺序需要进行的乘法次数。
数据范围:矩阵个数:1≤n≤15 1≤n≤15 ,行列数:1≤rowi,coli≤100 1≤rowi,coli≤100 ,保证给出的字符串表示的计算顺序唯一。
进阶:时间复杂度:O(n) O(n) ,空间复杂度:O(n) O(n)
输入描述:
输入多行,先输入要计算乘法的矩阵个数n,每个矩阵的行数,列数,总共2n的数,最后输入要计算的法则
计算的法则为一个字符串,仅由左右括号和大写字母(‘A’~‘Z’)组成,保证括号是匹配的且输入合法!
输出描述:
输出需要进行的乘法次数
示例1
输入:
3
50 10
10 20
20 5
(A(BC))
输出:
3500
逆波兰表达式的生成
参考:https://www.cnblogs.com/feika/p/3607431.html
普通表达式一般由数字、变量与±*/()运算符号组成。
例如:
(a+b)*3 - (a-b)/2
其逆波兰表达式是: a b + 3 * a b - 2 / -
本质上,普通表达式是中序表达式,逆波兰表达式是后序表达式。
一)、由普通表达式生成逆波兰表达式
1、初始化1个逆波兰字符串变量outstr,以及1个符号栈;自左向右输入表达式串; 2、如果当前字符为数值或变量,则直接添加到逆波兰字符串后 outstr;
3、如果当前字符为运算符号,如果是“(”,则直接压入符号栈;如果是“)”,则从栈中逐项pop运算符号,追加在outstr后;如果是其他运算符号,比较当前与栈顶的运算符优先级,如果当前低,则pop栈顶运算符,压入当前运算符号;如果当前的高,则直接压入栈中;
4、遇到结束符号时,逐项从栈中pop运算符项;
二)、计算逆波兰表达式的值
1、自左向右输入逆波兰表达式串;
2、如果当前为操作数,则直接压入栈;
3、如果当前为运算符号,则从栈顶两个进行计算,并将计算结果压入栈中;
4、最后从栈中pop出最终运算结果。
代码
# 逆波兰表达式法
def getPrefixExpression(exp_str):
prefix_exp_str = ""
ope_stack = []
last_ope = ""
for ope_ in exp_str:
if(ope_ == "("):
if(last_ope != "("): ope_stack.append('*')
ope_stack.append(ope_)
elif(ope_ == ")"):
while(ope_stack[-1]!="("):
prefix_exp_str += ope_stack.pop()
ope_stack.pop()
else:
if(last_ope != "("): ope_stack.append('*')
prefix_exp_str += ope_
last_ope = ope_
return prefix_exp_str
def getMultiplyFre(mats_info,exp_str):
prefix_exp_str = getPrefixExpression(exp_str)
#print(prefix_exp_str)
data_stack = []
multiply_cnt = 0
for ope_ in prefix_exp_str:
if(ope_!= "*"):
data_stack.append(mats_info.pop(0))
else:
mat2 = data_stack.pop()
mat1 = data_stack.pop()
res_mat,multiply_fre = matMultiply(mat1,mat2)
multiply_cnt += multiply_fre
data_stack.append(res_mat)
return multiply_cnt
def matMultiply(mat1,mat2):
res_mat = [mat1[0],mat2[1]]
multiply_fre = mat1[0]*mat1[1]*mat2[1]
return res_mat,multiply_fre
# 怎么这么多括号题
mat_num = int(input())
mats_info = []
for i in range(mat_num): mats_info.append(list(map(int,input().split())))
exp_str = list(input())
mulitply_fre = getMultiplyFre(mats_info,exp_str)
print(mulitply_fre)
传统算中缀表达式的解法:
def getMultiplyFre(mats_info,exp_str):
data_stack = []
ope_stack = []
multiply_cnt = 0
while(exp_str):
ope_str = exp_str.pop(0)
if(ope_str == "("):
ope_stack.append(ope_str)
elif(ope_str == ")"):
temp_data_stack = []
while(True):
ope_str = ope_stack.pop()
if(ope_str == "("): break
temp_data_stack.append(data_stack.pop())
if(temp_data_stack):
while(len(temp_data_stack)!=1):
mat1 = temp_data_stack.pop()
mat2 = temp_data_stack.pop()
res_mat,multiply_fre = matMultiply(mat1,mat2)
multiply_cnt += multiply_fre
temp_data_stack.append(res_mat)
data_stack.append(temp_data_stack.pop())
ope_stack.append("*")
else:
data_stack.append(mats_info.pop(0))
ope_stack.append("*")
return multiply_cnt
def matMultiply(mat1,mat2):
res_mat = [mat1[0],mat2[1]]
multiply_fre = mat1[0]*mat1[1]*mat2[1]
return res_mat,multiply_fre
# 怎么这么多括号题
mat_num = int(input())
mats_info = []
for i in range(mat_num): mats_info.append(list(map(int,input().split())))
exp_str = list(input())
mulitply_fre = getMultiplyFre(mats_info,exp_str)
print(mulitply_fre)