题解 | #矩阵乘法计算量估算#
矩阵乘法计算量估算
http://www.nowcoder.com/practice/15e41630514445719a942e004edc0a5b
把数字四则运算的方法改成矩阵乘法
1.算数:左括号和右括号优先级最低
左括号必须入栈
右括号不入栈,只用于带走左括号
优先级小于等于optr栈顶运算符时,弹出opnd中的两个元素和optr的栈顶做计算,计算结果再压入opnd栈,同时num+=m*n*q
2.矩阵乘法:A m*n B n*q
(AB) m*q,运算次数:m*n*q,连乘时相加
3.操作字符串的处理:寻找字符对应元素的row和col
if(act[i]>='A'&&act[i]<='Z'){matrix p;p.row=ma[act[i]-'A'].row;p.col=ma[act[i]-'A'].col;opnd.push(p);}
4.关于添加乘号:(要细心)字母的后面不是右括号、自己不是尾巴、前面是左括号
if(act[i]>='A'&&act[i]<='Z'&&act[i+1]!=')'&&i!=act.length()-1) { act.insert(act.begin()+i+1,'*'); } else if((act[i]>='A'&&act[i]<='Z'&&act[i-1]==')')||(act[i]=='('&&act[i-1]==')')) { act.insert(act.begin()+i,'*'); }
总代码:
/*矩阵乘法的运算量与矩阵乘法的顺序强相关。 例如: A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵 计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法, 后者只需要3500次。 编写程序计算不同的计算顺序需要进行的乘法次数。 输入描述: 输入多行,先输入要计算乘法的矩阵个数n, 每个矩阵的行数,列数,总共2n的数, 最后输入要计算的法则:一个字符串,仅由左右括号和大写字母('A'~'Z')组成, */ #include<iostream> #include<stack> using namespace std; typedef struct matrix { int row; int col; }matrix; matrix multiply(matrix a,matrix b,char p) { matrix result; result.row=a.row; result.col=b.col; return result; } int priority(char c) { switch(c) { case '(':return 1;break; case ')':return 1;break; case '*':return 2;break; default: return -1; } } int main() { int n; long int num=0;//乘法次数 stack<matrix> opnd; stack<char> optr; matrix ma[15]; string act; cin>>n; for(int i=0;i<n;i++) { cin>>ma[i].row>>ma[i].col; } cin>>act; for(int i=0;i<act.length();i++) { if(act[i]>='A'&&act[i]<='Z'&&act[i+1]!=')'&&i!=act.length()-1) { act.insert(act.begin()+i+1,'*'); } else if((act[i]>='A'&&act[i]<='Z'&&act[i-1]==')')||(act[i]=='('&&act[i-1]==')')) { act.insert(act.begin()+i,'*'); } } // cout<<act<<endl; for(int i=0;i<act.length();i++) { if(act[i]>='A'&&act[i]<='Z') { matrix p; p.row=ma[act[i]-'A'].row; p.col=ma[act[i]-'A'].col; opnd.push(p); } else if(act[i]=='*'||act[i]=='('||act[i]==')') { if(optr.empty()||priority(act[i])>priority(optr.top())||act[i]=='(')//优先级低或者为左括号 optr.push(act[i]); else { while(!optr.empty()&&priority(act[i])<=priority(optr.top())) { if(act[i]==')'&&optr.top()=='(') { optr.pop(); break; } matrix p=opnd.top(); opnd.pop(); matrix q=opnd.top(); opnd.pop(); opnd.push(multiply(q,p,optr.top())); num+=q.col*q.row*p.col; optr.pop(); } if(act[i]!=')') optr.push(act[i]); } } } // while(!opnd.empty()) // { // cout<<opnd.top().row<<" "<<opnd.top().col<<endl; // opnd.pop(); // } cout<<num<<endl; }