【算法导论】--分治策略Strassen算法(运用下标运算)【c++】
由于偷懒不想用泛型,所以直接用了整型来写了一份
①首先你得有一个矩阵的class Matrix
②Matrix为了方便用下标进行运算,
Matrix的结构如图:(我知道我的字丑。。。)

Matrix.h代码如下:(个人并不喜欢把代码全写在一块,对于阅读者是相当巨大的负担,其实自己受不了(逃))
#pragma once
#include<vector>
using namespace std;
class Matrix
{
public:
vector<vector<int>> nums;
int x0, y0; int size;
Matrix();
~Matrix();
Matrix(int size, int x0, int y0);
Matrix(Matrix input, int x0, int y0, int size);
Matrix(vector<vector<int>>input);
void Display();
static void MatrixMultiInit(Matrix &A, Matrix &B);
static Matrix MatrixMulti(Matrix A, Matrix B);
static Matrix MatrixAdd(Matrix A, Matrix B);
static Matrix MatrixSub(Matrix A, Matrix B);
};
Matrix.cpp对类的实现
一,构造,析构函数
Matrix::Matrix()
{
} Matrix::~Matrix()
{
} Matrix::Matrix(int size, int x0, int y0)
{
vector<vector<int>> temp(size, *new vector<int>(size));
for (int i = ; i < size; i++)
for (int j = ; j < size; j++)
temp[i][j] = ;
this->nums = temp;
this->x0 = x0;
this->y0 = y0;
this->size = size; } Matrix::Matrix(Matrix input, int x0, int y0, int size)
{
this->nums = input.nums;
this->x0 = x0;
this->y0 = y0;
this->size = size;
} Matrix::Matrix(vector<vector<int>> input)
{
this->nums = input;
this->x0 = ;
this->y0 = ;
this->size = input.size();
}
二,A+B,A-B实现
Matrix Matrix::MatrixAdd(Matrix A, Matrix B)
{
Matrix result(A.size, , );
for (int i = ; i < result.nums.size(); i++)
for (int j = ; j < result.nums.size(); j++)
result.nums[i][j] = A.nums[A.x0 + i][A.y0 + j] + B.nums[B.x0 + i][B.y0 + j];
return result;
} Matrix Matrix::MatrixSub(Matrix A, Matrix B)
{ Matrix result(A.size, , );
for (int i = ; i < result.nums.size(); i++)
for (int j = ; j < result.nums.size(); j++)
result.nums[i][j] = A.nums[A.x0 + i][A.y0 + j] - B.nums[B.x0 + i][B.y0 + j];
return result;
}
三,A*B的实现
Matrix Matrix::MatrixMulti(Matrix A, Matrix B)
{
int n = A.size;
int halfsize =n / ;
Matrix result(n, , );
if (n == )
result.nums[][] = A.nums[A.x0][A.y0] * B.nums[B.x0][B.y0];
else
{
Matrix tempS[];
for (int i = ; i < ; i++)
{
tempS[i] = *new Matrix(halfsize, , );
} //00-- A.x0,A.y0,halfsize
//01-- A.x0,A.y0+halfsize,halfsize
//10-- A.x0+halfsize,A.y0,halfsize
//11-- A.x0+halfsize,A.y0+halfsize,halfsize //00-- B.x0,B.y0,halfsize
//01-- B.x0,B.y0+halfsize,halfsize
//10-- B.x0+halfsize,B.y0,halfsize
//11-- B.x0+halfsize,B.y0+halfsize,halfsize
tempS[] = tempS[].MatrixSub(*new Matrix(B, B.x0, B.y0 + halfsize, halfsize), *new Matrix(B, B.x0 + halfsize, B.y0 + halfsize, halfsize));//01-11 B
tempS[] = tempS[].MatrixAdd(*new Matrix(A, A.x0, A.y0, halfsize), *new Matrix(A, A.x0, A.y0 + halfsize, halfsize));//00+01 A
tempS[] = tempS[].MatrixAdd(*new Matrix(A, A.x0 + halfsize, A.y0, halfsize), *new Matrix(A, A.x0 + halfsize, A.y0 + halfsize, halfsize));//10+11 A
tempS[] = tempS[].MatrixSub(*new Matrix(B, B.x0 + halfsize, B.y0, halfsize), *new Matrix(B, B.x0, B.y0, halfsize));//10-00 B
tempS[] = tempS[].MatrixAdd(*new Matrix(A, A.x0, A.y0, halfsize), *new Matrix(A, A.x0 + halfsize, A.y0 + halfsize, halfsize));//00+11 A
tempS[] = tempS[].MatrixAdd(*new Matrix(B, B.x0, B.y0, halfsize), *new Matrix(B, B.x0 + halfsize, B.y0 + halfsize, halfsize));//00+11 B
tempS[] = tempS[].MatrixSub(*new Matrix(A, A.x0, A.y0 + halfsize, halfsize), *new Matrix(A, A.x0 + halfsize, A.y0 + halfsize, halfsize));//01-11 A
tempS[] = tempS[].MatrixAdd(*new Matrix(B, B.x0 + halfsize, B.y0, halfsize), *new Matrix(B, B.x0 + halfsize, B.y0 + halfsize, halfsize));//10+11 B
tempS[] = tempS[].MatrixSub(*new Matrix(A, A.x0, A.y0, halfsize), *new Matrix(A, A.x0 + halfsize, A.y0, halfsize));//00-10 A
tempS[] = tempS[].MatrixAdd(*new Matrix(B, B.x0, B.y0, halfsize), *new Matrix(B, B.x0, B.y0 + halfsize, halfsize));//00+01 B Matrix tempP[];
for (int i = ; i < ; i++)
{
tempP[i] = *new Matrix(n / , , );
}
tempP[] = tempP[].MatrixMulti(*new Matrix(A, A.x0, A.y0, halfsize), *new Matrix(tempS[], , , halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , ,halfsize), *new Matrix(B, B.x0 + halfsize, B.y0 + halfsize, halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , , halfsize), *new Matrix(B, B.x0, B.y0, halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(A, A.x0 + halfsize, A.y0 + halfsize, halfsize), *new Matrix(tempS[], , , halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , , halfsize), *new Matrix(tempS[], , , halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , , halfsize), *new Matrix(tempS[], , , halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , , halfsize), *new Matrix(tempS[], , , halfsize)); Matrix result00 = result00.MatrixAdd(tempP[], tempP[]);
result00 = result00.MatrixSub(result00, tempP[]);
result00 = result00.MatrixAdd(result00, tempP[]);
Matrix result01 = result01.MatrixAdd(tempP[], tempP[]);
Matrix result10 = result10.MatrixAdd(tempP[], tempP[]);
Matrix result11 = result11.MatrixAdd(tempP[], tempP[]);
result11 = result11.MatrixSub(result11, tempP[]);
result11 = result11.MatrixSub(result11, tempP[]); if (n == ) {
for(int i=;i<n/+;i++)
for (int j = ; j < n / + ; j++) { result.nums[i][j]= result00.nums[i][j];
result.nums[i][j+n/+] = result01.nums[i][j];
result.nums[i+n/+][j] = result10.nums[i][j];
result.nums[i+n/+][j+n/+] = result11.nums[i][j];
}
} for(int i=;i<n/;i++)
for (int j = ; j < n / ; j++) { result.nums[i][j]= result00.nums[i][j];
result.nums[i][j+n/] = result01.nums[i][j];
result.nums[i+n/][j] = result10.nums[i][j];
result.nums[i+n/][j+n/] = result11.nums[i][j];
} }
return result;
}
四,防止size%2!=0的处理函数(即矩阵的行列数为奇数)
void Matrix::MatrixMultiInit(Matrix &A, Matrix &B) {
if (A.nums.size() % != )
{
for (int i = ; i < A.nums.size(); i++)
A.nums[i].push_back();
for (int i = ; i < B.nums.size(); i++)
B.nums[i].push_back();
A.nums.push_back(*new vector<int>(A.nums[].size(), ));
B.nums.push_back(*new vector<int>(B.nums[].size(), ));
A.size++;
B.size++;
}
}
五,输出函数(这个读者随意)
void Matrix::Display()
{
for (int i = ; i < this->nums.size(); i++) { cout << "||";
for (int j = ; j < this->nums[i].size(); j++) {
cout << this->nums[i][j] << " ";
}
cout << "||" << endl; }
}
六,测试函数
#include <iostream>
#include"Matrix.h"
int main()
{
vector<vector<int>> input = {
{,,},
{,,},
{,,},
};
Matrix test0 (input);
Matrix test1 (input);
Matrix test2;
test2.MatrixMultiInit(test0, test1);
test2= test2.MatrixMulti(test0, test1);
test2.Display(); }
本人比较愚笨,耗时一天半才完成,不知道是不是天气热的原因,人太燥了,沉不下心来思考bug。
A*B有一点需要注意的是分块的逻辑应该怎么表示,一开始我用了两个顶点来表示一个矩阵的分块,如图:

然后halfsize还得一个一个的算,然后自己敲错的几率还会加大,并且还不一定表示正确每个分块,然后就逼疯自己了。
感觉这两天被这一堆bug都弄自闭了。。。。
幸好还是撑过来了,这算是我啃算法导论的第一个坎吧。
幸好第二天在csdn里面看到了别人怎么分块的。看到了一个变量halfsize,于是才开始改自己Matrix的构造。
虽然一开始不愿意,但是改完之后,竟然一次过了!woc!
给我了一个教训,以后能“少”一个变量尽量“少”一个变量。
【算法导论】--分治策略Strassen算法(运用下标运算)【c++】的更多相关文章
- 算法导论-矩阵乘法-strassen算法
目录 1.矩阵相乘的朴素算法 2.矩阵相乘的strassen算法 3.完整测试代码c++ 4.性能分析 5.参考资料 内容 1.矩阵相乘的朴素算法 T(n) = Θ(n3) 朴素矩阵相乘算法,思想明了 ...
- 基于visual Studio2013解决算法导论之008快速排序算法
题目 快速排序 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...
- 《算法导论》——MaximumSubArray
今天我们讨论的算法是最大子数组问题. 首先我定义了一个类用来保存最大子数组的开始位置索引.结束位置索引和该数组的和.代码如下: class MaximumSubArray { private: int ...
- "《算法导论》之‘图’":深度优先搜索、宽度优先搜索(无向图、有向图)
本文兼参考自<算法导论>及<算法>. 以前一直不能够理解深度优先搜索和广度优先搜索,总是很怕去碰它们,但经过阅读上边提到的两本书,豁然开朗,马上就能理解得更进一步. 下文将会用 ...
- 《算法导论》——MergeSort
前言: 在今后的日子里,我将持续更新博客,讨论<算法导论>一书中的提到的各算法的C++实现.初来乍到,请多指教. 今日主题: 今天讨论<算法导论>第二章算法基础中的归并排序算法 ...
- 第四章 分治策略 4.2 矩阵乘法的Strassen算法
package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import ...
- 【技术文档】《算法设计与分析导论》R.C.T.Lee等·第4章 分治策略
分治策略有一种“大事化小,小事化了”的境界,它的思想是将原问题分解成两个子问题,两个子问题的性质和原问题相同,因此这两个子问题可以再用分治策略求解,最终将两个子问题的解合并成原问题的解.有时,我们会有 ...
- 【从零学习经典算法系列】分治策略实例——高速排序(QuickSort)
在前面的博文(http://blog.csdn.net/jasonding1354/article/details/37736555)中介绍了作为分治策略的经典实例,即归并排序.并给出了递归形式和循环 ...
- 【算法导论C++代码】Strassen算法
简单方阵矩乘法 SQUARE-MATRIX-MULTIPLY(A,B) n = A.rows let C be a new n*n natrix to n to n cij = to n cij=ci ...
随机推荐
- delphi TAdoQuery组件的close方法可能导致”列名无效“错误
1,故障现象 一次程序运行,出现如下错误: 对应代码如下: 2,故障分析 Query_alert_2的语句在查询分析器中单独执行是正常的.排除语句出错. 如果注解掉Query_alert_1,则错误变 ...
- Java并发包--LinkedBlockingDeque
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3503480.html LinkedBlockingDeque介绍 LinkedBlockingDeque ...
- 怎奈风云多变换,骚完一波还一波,记PHP mongodb驱动的2019年11月用法
怎么,觉得pecl下一个扩展包,phpize make make install php.ini里引用一下 mongodb.so就万事大吉了? Deeply Sorry!看到MongoDB\Driv ...
- python文件操作知识点总结:写入篇
文件写入: 文中的两个变量:f 和 f1(截图时被该死的灯泡遮挡住了) 被称作文件对象 或文件句柄(重口味的叫法,感觉很C++,句子又不是刀子,怎么还带柄?) 以逗号为界,open()方法所依赖的3个 ...
- 51nod 1843 排列合并机(DP+组合)
题解链接 不过求ggg不用O(n2)DPO(n^2)DPO(n2)DP,g[n]g[n]g[n]直接就是卡特兰数的第n−1n-1n−1项.即: g[n]=(2(n−1)n−1)−(2(n−1)n−2) ...
- PHP mysqli_commit() 函数
关闭自动提交,做一些查询,然后提交查询: <?php // 假定数据库用户名:root,密码:123456,数据库:RUNOOB $con=mysqli_connect("localh ...
- 安裝開源BBS軟件YAF時碰到的問題
1.下載 http://yetanotherforum.net/download.aspx 安裝說明 http://www.drreddys.com/quest/readme.htm 其實只要打開根目 ...
- Eclipse的快捷键设置及使用
Eclipse快捷键的设置和使用 java程序开发,经常会用Eclipse或者MyEclise集成开发环境,一些实用的Eclipse快捷键和使用技巧, 可以在平常开发中节约出很多时间提高工作效率,下面 ...
- https服务
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/bright69/article/deta ...
- 八十年代的经典 NFS和AFS
NFS:(C/S模式) 大体架构: 1985年Sun公司基于UDP开发了网络共享文件系统(Network FileSystem) NFS由一系列NFS命令和进程组成的客户机/服务器模式,在第三版中加入 ...