【算法导论】--分治策略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 ...
随机推荐
- Task.Run 和 Task.Factory.StartNew 区别
Task.Run 是在 dotnet framework 4.5 之后才可以使用, Task.Factory.StartNew 可以使用比 Task.Run 更多的参数,可以做到更多的定制. 可以认为 ...
- IdentityServer(三)密码模式
前言 用户名密码模式相较于客户端凭证模式,多了用户.通过用户的用户名和密码向Identity Server申请访问令牌.密码模式有两种实现方式. 1.把用户写进内存Identity从中读取账号密码验证 ...
- python高性能编程方法一
python高性能编程方法一 阅读 Zen of Python,在Python解析器中输入 import this. 一个犀利的Python新手可能会注意到"解析"一词, 认为 ...
- mouseleave([[data],fn])
mouseleave([[data],fn]) 概述 当鼠标指针离开元素时,会发生 mouseleave 事件.该事件大多数时候会与mouseenter 事件一起使用. 与 mouseout 事件不同 ...
- Java进阶知识20 Spring的代理模式
本文知识点(目录): 1.概念 2.代理模式 2.1.静态代理 2.2.动态代理 2.3.Cglib子类代理 1.概念 1.工厂模式 2. 单例模式 代理(Proxy ...
- Bzoj 3942: [Usaco2015 Feb]Censoring(kmp)
3942: [Usaco2015 Feb]Censoring Description Farmer John has purchased a subscription to Good Hooveske ...
- 删数问题(SDUT2072 )
删数问题 Time Limit: 1000 msMemory Limit: 65536 KiB Problem Description 键盘输入一个高精度的正整数n(≤100位),去掉其中任意s个数字 ...
- html 刷新更新背景图
需求:每次刷新页面,随机获取背景图 实现方式: 1 通过js动态生成标签 <body> <script type="text/javascript"> va ...
- mysql.zip版本的安装教程
MySQL zip版本安装 一直以来都习惯了使用MySQL安装文件(.exe),今天下载了一个.zip版本的MySQL,安装过程中遇到了一些问题,如下: 1.在MySQL官网上(http://dev. ...
- HTTP之缓存
1. 保持副本的新鲜 HTTP 有一些简单的机制可以在不要求服务器记住有哪些缓存拥有其文档副本的情况下,保持已缓存数据与服务器数据之间充分一致.HTTP 将这些简单的机制称为文档过期(document ...