HJ70_矩阵乘法计算量估算_入门栈使用的典型题

Posted Aneverforget

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HJ70_矩阵乘法计算量估算_入门栈使用的典型题相关的知识,希望对你有一定的参考价值。

反思:

这题咋一看不难,但是越做坑越多,按照一开始不完善的思路无法完全通过测试。

参看高赞答案,代码行数特少。但是没考虑一个括号中有三个矩阵的情况。

思路:

1、判断哪两个矩阵开始相乘的条件:遇到“)”时,该字符前两个矩阵开始相乘。把相乘后矩阵行列数组压入栈栈中。该题默认不存在(A(BCD))一个括号中有三个矩阵的情况。如果一个括号中有三个及以上矩阵可以参考原来的错误答案。

2、采用order(i)-65的方法获取压入栈的矩阵,这种方法使代码更简洁。

参考高赞答案后通过测试的代码:

 #a=[[\'5\'], [\'23\', \'61\'], [\'61\', \'59\'], [\'59\', \'34\'],[\'34\', \'56\'], [\'56\', \'35\'],[\'(A(((BC)D)E))\']]
 b=[[\'47\', \'45\'], [\'45\', \'31\'], [\'31\', \'20\'],[\'20\', \'35\'], 
    [\'35\', \'59\'],[\'59\', \'42\'],[\'42\', \'28\']]#这种情况矩阵相乘要放进“(”判断循环中,边判断边处理
 #ord(“A")=65
 temp=[]
 for i in b:
     temp.append(list(map(int,i)))
 print(temp)
 f=[\'(A((B(C(DE)))(FG)))\']
 arr=[]
 sum1=0
 for i in f[0]:
     if i.isalpha():
         arr.append(temp[ord(i)-65])#获得压入栈中矩阵。
     #print(arr)
     elif i==")" and len(arr)>=2:
         matrix1=arr.pop()
         matrix2=arr.pop()
         a,b,c=matrix2[0],matrix1[1],matrix2[1]
         arr.append([a,b])#把两矩阵相乘得到的新矩阵的行列压入栈中。
         sum1=a*b*c+sum1
 print(sum1)
     

只通过18个测试案例的代码

 a=[[\'5\'], [\'23\', \'61\'], [\'61\', \'59\'], [\'59\', \'34\'],[\'34\', \'56\'], [\'56\', \'35\'],[\'(A(((BC)D)E))\']]
 n=[]*len(a)
 for line in a[:-1]:
     n.append(list(map(int,line)))
 a=n+a[-1]
 n.pop(0)
 t1,t2,t=[],[],[]  
 for k,i in enumerate(a[-1]):
     if i=="(":
         t1.append(k)
     elif i==")":
         t2.append(k)
     else:
         t.append(k)
 print(t1,t2,t)
 d=dict(zip(t,n))
 #print(d)
 def nu(t1:int,t2:int,t)->int:
     num=0
     tt,now=[],[]
     for j in t:
         if j in range(t1,t2):
             num+=1
             now.append(j)
         else:
             tt.append(j)
     return tt,now
 def su(now,fresult):
     l=[]
     sum1=0
     for i in now:
         l.append(d[i])
     if fresult:    
         if list(fresult.keys())[0]<now[0]:
             print(l)
             l.insert(0,list(fresult.values())[0])
             print(l)
         else:
             l.append(list(fresult.values())[0])
     repeat=len(l)-1
     for i in range(repeat):
         c,b=l[-1][0],l[-1][1]
         a=l[-2][0]
         print(a,b,c,sum1)
         sum1=sum1+a*b*c
         l.pop()
         l.pop()
         l.append([a,b])
         fresult=now[0]:[a,b]
         print(a,b,c,fresult)
     return sum1,fresult
 sum2=0
 fresult=
 while t:
     t,now=nu(t1.pop(),t2.pop(0),t)    
     
     sum1,fresult=su(now,fresult)
     sum2=sum2+sum1
     print(now,fresult,t) 
 print(sum2)

 

华为机试HJ70:矩阵乘法计算量估算

作者:Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

题目描述:

矩阵乘法的运算量与矩阵乘法的顺序强相关。
例如:

A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵

计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。

编写程序计算不同的计算顺序需要进行的乘法次数。

本题含有多组样例输入!

输入描述:

输入多行,先输入要计算乘法的矩阵个数n,每个矩阵的行数,列数,总共2n的数,最后输入要计算的法则
计算的法则为一个字符串,仅由左右括号和大写字母('A'~'Z')组成,保证括号是匹配的且输入合法!

输出描述:

输出需要进行的乘法次数

示例:

输入:

3
50 10
10 20
20 5
(A(BC))

输出:

3500

解题思路:

本题我用二维数组做的,采用了指针方式,用vector也很方便。Estimate函数用来计算两个矩阵的计算量,并返回相乘后的矩阵;calc函数用来将vector中后面的两个矩阵拿出来计算,再将新生成的矩阵塞进去,以此实现矩阵的连续操作;solve函数是主要求解函数,遍历字符串,将出现的矩阵字母以此塞进vector中,每出现一次')',就进行一个calc计算,这样实现了括号的优先级,若最后遍历完字符串,vector尺寸大于1,类似A(BC)=AD这样的,那就继续执行calc。完毕。

其实题目描述的不是特别严谨,假设括号并不是最小囊括两个,比如((ABC)D),按照我所写的算法逻辑,就会先算BC=E,再算ED=F,再算AF,但实际上应该是ABC=G,再算GD。总的来说,根据不同的题目要求,代码应该有所变通和完善,当前的测试样例不涵盖此类情况,如果未来有不通的案例,可以评论私我~

测试代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int* Estimate(int *t1,int *t2,int &sum)
{
    int t1_row=t1[0];
    int t1_col=t1[1];
    int t2_row=t2[0];
    int t2_col=t2[1];
    sum=t1_row*t1_col*t2_col;
    int *t3=new int[2];
    t3[0]=t1_row;
    t3[1]=t2_col;
    return t3;
}

int calc(vector<int*> &m)
{
    int *t1;
    int *t2;
    int *t3;
    int sum=0;
    t2=m.back();
    m.pop_back();
    t1=m.back();
    m.pop_back();
    t3=Estimate(t1,t2,sum);
    m.push_back(t3);
    return sum;
}

int solve(int *a[2],string str)
{
    vector<int*> m;
    int sum=0;
    int k=0;
    for(int i=0;i<str.size();++i)
    {
        // 若有')',则对前面的两个矩阵进行了一次计算量估算
        if(str[i]==')')
        {
            sum+=calc(m);
        }
        else if(str[i]>='A'&&str[i]<='Z')
        {
            m.push_back(a[k]);
            k++;
        }
        // 如果是'(',跳过
    }
    while(m.size()>1)
    {
        sum+=calc(m);
    }
    return sum;
}

int main()
{
    int number;
    while(cin>>number)
    {
        int**mat=new int*[number];
        for(int i=0;i<number;++i)
        {
            mat[i]=new int[2];
            cin>>mat[i][0];
            cin>>mat[i][1];
        }
        string str;
        cin>>str;
        cout<<solve(mat,str)<<endl;
        delete[] mat;
    }
    return 0;
}

以上是关于HJ70_矩阵乘法计算量估算_入门栈使用的典型题的主要内容,如果未能解决你的问题,请参考以下文章

矩阵乘法计算量估算

矩阵乘法计算量估算, 华为笔试题

「CSPS 2019 十一」三地联考

解题(JuZhengCalculate-矩阵乘法计算量)

算法导论--动态规划(矩阵链乘法)

华为机试HJ69:矩阵乘法