例如说,有四个矩阵ABCD相乘,那么所有的完全加括号结果为(A((BC)D)) (A(B(CD))) ((AB)(CD)) (((AB)C)D) (A(BC))D)。要求输出n个矩阵连乘所有的完全加括号结果。

解决方法一

  1. 基本思想:首先从1,2,3,4个矩阵的角度来归纳。如果只有一个矩阵A,那么很明显所有的完全加括号结果就是A本身。如果有两个矩阵A,B相乘,很明显所有的完全加括号结果就是AB。如果有三个矩阵A,B,C相乘,那么我们将考虑将矩阵链断开,分为两个子矩阵链,然后分别求取两个子矩阵链的所有完全加括号结果的集合,最后再求出这两个集合的笛卡儿积即可。此时三个矩阵共有两种断开方式:A,BC和AB,C。第一种断开方式中,左子矩阵链为A,该子矩阵链的所有完全加括号结果的集合已知为{A},右子矩阵链为BC,该子矩阵链的所有完全加括号结果的集合已知为{BC}。那么该断开方式的完全加括号结果为A(BC)。由此类推另外一种断开方式的完全加括号结果为(AB)C。所以,三个矩阵相乘的所有完全加括号结果为{A(BC),(AB)C}。如果有四个矩阵A,B,C,D相乘,断开方式有:A,BCD和AB,CD和ABC,D。第一种断开方式中,左子矩阵链为A,该子矩阵链的所有完全加括号结果的集合已知为{A},右子矩阵链为BCD,从前面分析可知其所有完全加括号结果为{B(CD),(BC)D},该断开方式的所有完全加括号结果为:A(B(CD))和A((BC)D),以此类推下去,我们可以发现n个矩阵划分的子矩阵链均可以在1~n-1个矩阵中找到对应的矩阵链。因此,要求出n个矩阵相乘的所有完全加括号结果,可以先从1个矩阵入手,求出这n个矩阵每一个矩阵的所有完全加括号结果并储存起来,再计算这n个矩阵每两个相邻矩阵的所有完全加括号结果并储存起来,再计算这n个矩阵每三个相邻矩阵的所有完全加括号结果并储存起来,以此类推,最后计算出这n个矩阵每n个相邻矩阵的所有完全加括号结果即n个矩阵相乘的所有完全加括号结果。

  2. 基本过程:假设矩阵链为A_1 A_2… A_n,
    i.求出矩阵链每一个矩阵的所有完全加括号结果:A_1:{ A_1},A_2:{ A_2}
    ,…,A_n:{ A_n}
    ii.求出矩阵链每两个矩阵的所有完全加括号结果:A_1 A_2:{ A_1 A_2},A_2 A_3:{ A_2 A_3},…,A_(n-1) A_n:{ A_(n-1) A_n}
    iii.求出矩阵链每三个矩阵的所有完全加括号结果:A_1 A_2 A_3: { A_1 (A_2 A_3),(A_1 A_2)A_3},A_2 A_3 A_4: { A_2 (A_3 A_4), (A_2 A_3)A_4},…,A_(n-2) A_(n-1) A_n: { A_(n-1) (A_(n-1) A_n), (A_(n-2) A_(n-1))A_n}



    最后得到矩阵链的所有完全加括号结果。里面有一些细节值得注意,就是如何找到特定矩阵链的所有完全加括号结果?在这里我用了unordered_map容器,将特定的矩阵链作为键值,将该矩阵链的所有完全加括号结果集合作为映射值,这样就能在较短时间内找到想要的结果。

  3. 代码

#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<ctime>
using namespace std;
clock_t start,end_t;int main()
{cout << "输入矩阵相乘的个数:";int n;cin >> n;cout << n <<"个元素的矩阵序列如下:";string str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", str2 = str1.substr(0, n);cout << str2<< endl;cout << n << "个矩阵相乘的所有完全加括号结果:" << endl;start = clock();if (n == 1)cout << "A" << endl;else if (n == 2)cout << "AB" << endl;else if (n == 3)cout << "(AB)C\nA(BC)" << endl;else{unordered_map<string, vector<string>> record;for (int i = 0; i < n; i++){string t1(1,str2[i]);record[t1] = {t1}; //保存一个矩阵的所有完全加括号结果 }for (int i = 0; i < n-1; i++){string t2(2, 'x');t2[0] = str2[i];t2[1] = str2[i + 1];record[str2.substr(i, 2)] = {t2}; //保存每两个相邻矩阵的所有完全加括号结果 }for(int t = n -2; t >= 1; t--){for (int i = 0; i < t; i++){string t3 = str2.substr(i, n - t + 1); //取出矩阵链每n-t-1个相邻矩阵(3-n) for (int j = 1; j < n - t + 1; j++){string t4 = t3.substr(0, j); //断开 string t5 = t3.substr(j, n - t - j + 1);int count1 = record[t4].size(), count2 = record[t5].size();for (int k1 = 0; k1 < count1; k1++) //求出两个集合的笛卡儿积 {for (int k2 = 0; k2 < count2; k2++){string t6;if (record[t4][k1].size() == 1)t6 += record[t4][k1];elset6 += "(" + record[t4][k1]+")";if (record[t5][k2].size() == 1)t6 += record[t5][k2];elset6 += "(" + record[t5][k2] + ")";record[t3].push_back(t6);}}}}//t--;}end_t = clock();double endtime = (double)(end_t-start)/CLOCKS_PER_SEC;cout << "Total time:" << endtime << endl; system("pause");vector<string>res = record[str2];for (string i : res)cout << i << endl;cout << "一共有" << res.size() << "种可能的输出." << endl;}return 0;
}

解决方法二
1.基本思想:如果题目的要求是输出有多少种矩阵连乘的完全加括号的形式,那么有以下实现方法:

//n表示矩阵链的矩阵数目
int f(int n)
{int num=0;if (n == 1)num = 1;elsefor (int i = 1; i != n; i++)num += f(i)*f(n - i); //左子矩阵链完全加括号的数目乘以右子矩阵链完全加括号的数目return num;
}

那么我们也可以考虑用这种方式来进行输出。

  • 若n=1,那么直接输出A(假设该矩阵为A)
  • 若n=2,那么直接输出(AB)(j假设该矩阵链为AB)
  • 若n>2,那么可以将矩阵链分为左子矩阵链和右子矩阵链,然后分别求左子矩阵链的所有完全加括号结果和右子矩阵链的所有完全加括号结果,最后再求他们的笛卡儿积。

2.代码

#include<iostream>
#include<vector>
#include<string>
using namespace std;vector<string> matrix_chain(string * p, int start, int length)
{vector<string> ret;if (length == 1) {ret.push_back(p[start]);}else if (length == 2) {ret.push_back("(" + p[start] + p[start + 1] + ")");}else {for (int i = 1; i != length; i++) {vector<string> part1 = matrix_chain(p, start, i);vector<string> part2 = matrix_chain(p, start + i, length - i);for (int k = 0; k != part1.size(); k++) {for (int m = 0; m != part2.size(); m++) {ret.push_back("(" + part1[k] + part2[m] + ")");}}}}return ret;
}int main()
{int n;cout << "请输入矩阵个数:";cin >> n;string* p = new string[n];  // 向量p用来存储n个矩阵for(int i=0; i!=n; i++){p[i] = char(i + char('A'));}vector<string> result = matrix_chain(p, 0, n);cout << "理论上,方案数量:" << f(n) << endl;cout << "矩阵链乘完全括号化方案数量:"<<result.size() << endl;for (int i = 0; i != result.size(); i++)cout << result[i] << endl;return 0;
}

输出矩阵连乘所有的完全加括号形式相关推荐

  1. 字符串加括号问题(矩阵乘法组合问题)C++

    矩阵乘法加括号问题 给定一个长度的字符串,很明显是可以加括号(矩阵乘法的结合律) 所以,一共有多少种加括号的方式呢? 给出了计算总共有多少这样组合 例如: 下面这个串,输入的长度为4. ABCD 所有 ...

  2. 【算法java版04】:顺时针方向循环输出矩阵

    顺时针方向循环输出矩阵 一.题目描述 二.实现思路 三.代码示例 四.测评结果 (1)4 x 4 矩阵: (2)3 x 3 矩阵: 一.题目描述 使用二维数组构建一个矩阵,按照顺时针方向循环输出矩阵内 ...

  3. java输入矩阵规格和行数,输出矩阵

    java键盘输入的小例子 键盘输入矩阵的行数和列数,再输入矩阵的内容,输出矩阵. 这样子写可以不受固定行数列数的限制,你自己来定义行数和列数,自己输入内容.也可以应用到计算矩阵的加减乘数里面,方便就对 ...

  4. 1155: 零起点学算法62——输出矩阵

    1155: 零起点学算法62--输出矩阵 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lld Submitted: 997   ...

  5. MATLAB小知识(三)——输出矩阵到TXT

    方法一:dlmwrite(验证可用) 版权声明:本文为CSDN博主「大芳同学」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog ...

  6. 简单了解latex输出矩阵

    简单了解latex输出矩阵 \begin{equation} \left( \begin{array}{ccc} a11 & a12 &a13\ a21 & a212 & ...

  7. 【C语言】编程实现输出矩阵上/下三角的数值。要求:输入一个正整数n和n阶矩阵的数值,打印输出矩阵、下三角和上三角的数值。

    [问题描述]编程实现输出矩阵上/下三角的数值.要求:输入一个正整数n和n阶矩阵的数值,打印输出矩阵.下三角和上三角的数值. [输入输出样例] [样例说明] 输入提示符中冒号为英文符号,后面无空格. 输 ...

  8. matlab fprintf输出矩阵

    a=[1,2,3;4,5,6]  是一个2×3矩阵 1 2 3 4 5 6 fid=fopen('d:\chr.txt','wt')  本命令用法网上可以查到,帮助文件里讲的也很清楚 fprintf( ...

  9. c语言 A21—求3*5矩阵每列最大值,输出矩阵和最大值

    c语言 A21-求3*5矩阵每列最大值,输出矩阵和最大值 题目:求一个3*5的矩阵各列元素的最大值,将原矩阵和求出的最大值全部输出. #include<stdio.h> int main( ...

最新文章

  1. Xamarin.Forms教程下载安装Xamarin.iOS
  2. Kingbase金仓更改表空间
  3. css:构建响应式网站
  4. python 任务调度 celery_python任务调度模块celery(二)
  5. Spring Quartz的原理
  6. mqtt发布json数据_微服务实战:从架构到发布(一)
  7. 信号与槽QVariant传递结构体指针
  8. 开机需要手动启动无线
  9. 从SVN上拉取代码到本地进行开发
  10. 地理加权回归学习记录
  11. photoshop2019及其破解器
  12. ftp主动模式与被动模式
  13. Javascript 8421
  14. Micro:Bit手柄试用之一MagicPad (解决蓝牙与gamePad包共存)
  15. 我喜欢你时的内心活动
  16. 你听说过FOC吗?FOC的原理是什么?
  17. Linux下禁用root远程登录并且新建一个用户赋予root权限
  18. MySQL8.0.11修改root密码
  19. Swift 3.0中GCD的常用方法
  20. Leetcode(1)——数组、栈、队列

热门文章

  1. windows对bat文件简单加密
  2. 手撸SSO单点登录(一):序言
  3. nn.Embedding(num_embeddings=vocab_size, embedding_dim=embed_dim)
  4. Navicat Premium 15数据库视图化软件最新安装详细教程讲解
  5. JavaScript Attacks
  6. C语言项目实战:《别踩白块游戏》零基础项目,137 行源代码示例
  7. Devexpress学习篇(请大家多多指教)
  8. linux 显示目录文件数,如何在Linux系统上显示当前及子目录中的文件数量
  9. 安卓TV开发(三) 移动智能设备之实现主流TV电视盒子焦点可控UI
  10. hMailServer 邮件系统配置