【算法导论】--分治策略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 ...
随机推荐
- MVVM框架(Vue)
问题: 一:说一下使用 JQuery和使用框架的区别? 二: 说一下对 MVVM的理解 三: Vue中如何实现响应式 四: vue中如何解析模板 五:vue整个实现流程 1. 说一下使用 JQuery ...
- JS 自定义组件
经常会用到JS插件,但从未研究过插件的写法 目前主流的写法有多种,各有各的优缺点,下面,我就以最常规的一种写法举例 // plugin.js ;(function(undefined) {//防止出现 ...
- C指针乱记
//int a[3][4] = { { 66, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }; //读取二维数组任意元素hint int(*)a[4] ...
- Java8-Lambda-No.05
import java.util.HashMap; import java.util.function.BiConsumer; public class Lambda5 { //Pre-Defined ...
- PageHelper使用中出现的问题
PageHelper在分页查询的时候功能强大,内部使用拦截器实现.这边文章做了详细的介绍. https://www.cnblogs.com/ljdblog/p/6725094.html https:/ ...
- django加载本地html
django加载本地html from django.shortcuts import render from django.http import HttpResponse from django. ...
- Activiti服务类- RepositoryService服务类
Activity服务类-1 RepositoryService服务类一共47个接口1.创建部署//开始创建一个新的部署.DeploymentBuilder createDeployment(); 2. ...
- About IndexDB
http://blog.csdn.net/bd_zengxinxin/article/details/7758317 HTML5 - Storage 客户端存储 http://html5demos.t ...
- Codeforces 1221 G Graph And Numbers
题面 这种比赛时只有11个人做出来的题一般来说都是暴难的, 我也不知道我怎么搞出来的www 看完这个题第一感觉就是要容斥,至少有一条某种边的方案已经比较难求了,而直接算三种边都至少存在一条的方案数就更 ...
- shell 字符串分割cut
cut 选项与参数 -d:后面接分隔字符.与-f一起使用. -f:依据-d的分隔字符将一段信息分隔数段,用-f取出第几段的意思. -c:以字符的单位取出固定字符区间 [zhang@localhost ...