c/c++语言开发共享【算法导论】–分治策略Strassen算法(运用下标运算)【c++】

由于偷懒不想用泛型,所以直接用了整型来写了一份 ①首先你得有一个矩阵的class Matrix ②Matrix为了方便用下标进行运算, Matrix的结构如图:(我知道我的字丑。。。) Matrix.h代码如下:(个人并不喜欢把代码全写在一块,对于阅读者是相当巨大的负担,其实自己受不了(逃)) Ma …

由于偷懒不想用泛型,所以直接用了整型来写了一份

①首先你得有一个矩阵的class matrix

②matrix为了方便用下标进行运算,

matrix的结构如图:(我知道我的字丑。。。)

【算法导论】--分治策略Strassen算法(运用下标运算)【c++】

 

 matrix.h代码如下:(个人并不喜欢把代码全写在一块,对于阅读者是相当巨大的负担,其实自己受不了(逃))

 1 #pragma once   2 #include<vector>   3 using namespace std;   4 class matrix   5 {   6 public:   7     vector<vector<int>> nums;   8     int x0, y0;   9   10     int size;  11     matrix();  12     ~matrix();  13     matrix(int size, int x0, int y0);  14     matrix(matrix input, int x0, int y0, int size);  15     matrix(vector<vector<int>>input);  16     void display();  17     static void matrixmultiinit(matrix &a, matrix &b);  18     static matrix matrixmulti(matrix a, matrix b);  19     static matrix matrixadd(matrix a, matrix b);  20     static matrix matrixsub(matrix a, matrix b);  21 };

 

 

matrix.cpp对类的实现

一,构造,析构函数

 1 matrix::matrix()   2 {   3 }   4    5    6 matrix::~matrix()   7 {   8 }   9   10 matrix::matrix(int size, int x0, int y0)  11 {  12     vector<vector<int>> temp(size, *new vector<int>(size));  13     for (int i = 0; i < size; i++)  14         for (int j = 0; j < size; j++)  15             temp[i][j] = 0;  16     this->nums = temp;  17     this->x0 = x0;  18     this->y0 = y0;  19     this->size = size;  20   21 }  22   23 matrix::matrix(matrix input, int x0, int y0, int size)  24 {  25     this->nums = input.nums;  26     this->x0 = x0;  27     this->y0 = y0;  28     this->size = size;  29 }  30   31 matrix::matrix(vector<vector<int>> input)  32 {  33     this->nums = input;  34     this->x0 = 0;  35     this->y0 = 0;  36     this->size = input.size();  37 }

 

二,a+b,a-b实现

 1 matrix matrix::matrixadd(matrix a, matrix b)   2 {   3     matrix result(a.size, 0, 0);   4     for (int i = 0; i < result.nums.size(); i++)   5         for (int j = 0; j < result.nums.size(); j++)   6             result.nums[i][j] = a.nums[a.x0 + i][a.y0 + j] + b.nums[b.x0 + i][b.y0 + j];   7     return result;   8 }   9   10 matrix matrix::matrixsub(matrix a, matrix b)  11 {  12   13     matrix result(a.size, 0, 0);  14     for (int i = 0; i < result.nums.size(); i++)  15         for (int j = 0; j < result.nums.size(); j++)  16             result.nums[i][j] = a.nums[a.x0 + i][a.y0 + j] - b.nums[b.x0 + i][b.y0 + j];  17     return result;  18 }

 

三,a*b的实现

 1 matrix matrix::matrixmulti(matrix a, matrix b)   2 {   3     int n = a.size;   4     int halfsize =n / 2;   5     matrix result(n, 0, 0);   6     if (n == 1)   7         result.nums[0][0] = a.nums[a.x0][a.y0] * b.nums[b.x0][b.y0];   8     else   9     {  10         matrix temps[10];  11         for (int i = 0; i < 10; i++)  12         {  13             temps[i] = *new matrix(halfsize, 0, 0);  14         }  15   16         //00--  a.x0,a.y0,halfsize  17         //01-- a.x0,a.y0+halfsize,halfsize  18         //10--  a.x0+halfsize,a.y0,halfsize  19         //11--    a.x0+halfsize,a.y0+halfsize,halfsize  20                   21         //00-- b.x0,b.y0,halfsize  22         //01-- b.x0,b.y0+halfsize,halfsize  23         //10-- b.x0+halfsize,b.y0,halfsize  24         //11--    b.x0+halfsize,b.y0+halfsize,halfsize  25         temps[0] = temps[0].matrixsub(*new matrix(b, b.x0, b.y0 + halfsize, halfsize), *new matrix(b, b.x0 + halfsize, b.y0 + halfsize, halfsize));//01-11 b  26         temps[1] = temps[1].matrixadd(*new matrix(a, a.x0, a.y0, halfsize), *new matrix(a, a.x0, a.y0 + halfsize, halfsize));//00+01 a  27         temps[2] = temps[2].matrixadd(*new matrix(a, a.x0 + halfsize, a.y0, halfsize), *new matrix(a, a.x0 + halfsize, a.y0 + halfsize, halfsize));//10+11 a  28         temps[3] = temps[3].matrixsub(*new matrix(b, b.x0 + halfsize, b.y0, halfsize), *new matrix(b, b.x0, b.y0, halfsize));//10-00 b  29         temps[4] = temps[4].matrixadd(*new matrix(a, a.x0, a.y0, halfsize), *new matrix(a, a.x0 + halfsize, a.y0 + halfsize, halfsize));//00+11 a  30         temps[5] = temps[5].matrixadd(*new matrix(b, b.x0, b.y0, halfsize), *new matrix(b, b.x0 + halfsize, b.y0 + halfsize, halfsize));//00+11 b  31         temps[6] = temps[6].matrixsub(*new matrix(a, a.x0, a.y0 + halfsize, halfsize), *new matrix(a, a.x0 + halfsize, a.y0 + halfsize, halfsize));//01-11 a  32         temps[7] = temps[7].matrixadd(*new matrix(b, b.x0 + halfsize, b.y0, halfsize), *new matrix(b, b.x0 + halfsize, b.y0 + halfsize, halfsize));//10+11 b  33         temps[8] = temps[8].matrixsub(*new matrix(a, a.x0, a.y0, halfsize), *new matrix(a, a.x0 + halfsize, a.y0, halfsize));//00-10 a  34         temps[9] = temps[9].matrixadd(*new matrix(b, b.x0, b.y0, halfsize), *new matrix(b, b.x0, b.y0 + halfsize, halfsize));//00+01 b  35   36   37         matrix tempp[7];  38         for (int i = 0; i < 7; i++)  39         {  40             tempp[i] = *new matrix(n / 2, 0, 0);  41         }  42         tempp[0] = tempp[0].matrixmulti(*new matrix(a, a.x0, a.y0, halfsize), *new matrix(temps[0], 0, 0, halfsize));  43         tempp[1] = tempp[1].matrixmulti(*new matrix(temps[1], 0, 0,halfsize), *new matrix(b, b.x0 + halfsize, b.y0 + halfsize, halfsize));  44         tempp[2] = tempp[2].matrixmulti(*new matrix(temps[2], 0, 0, halfsize), *new matrix(b, b.x0, b.y0, halfsize));  45         tempp[3] = tempp[3].matrixmulti(*new matrix(a, a.x0 + halfsize, a.y0 + halfsize, halfsize), *new matrix(temps[3], 0, 0, halfsize));  46         tempp[4] = tempp[4].matrixmulti(*new matrix(temps[4], 0, 0, halfsize), *new matrix(temps[5], 0, 0, halfsize));  47         tempp[5] = tempp[5].matrixmulti(*new matrix(temps[6], 0, 0, halfsize), *new matrix(temps[7], 0, 0, halfsize));  48         tempp[6] = tempp[6].matrixmulti(*new matrix(temps[8], 0, 0, halfsize), *new matrix(temps[9], 0, 0, halfsize));  49   50   51   52         matrix result00 = result00.matrixadd(tempp[4], tempp[3]);  53         result00 = result00.matrixsub(result00, tempp[1]);  54         result00 = result00.matrixadd(result00, tempp[5]);  55         matrix result01 = result01.matrixadd(tempp[0], tempp[1]);  56         matrix result10 = result10.matrixadd(tempp[2], tempp[3]);  57         matrix result11 = result11.matrixadd(tempp[4], tempp[0]);  58         result11 = result11.matrixsub(result11, tempp[2]);  59         result11 = result11.matrixsub(result11, tempp[6]);  60   61         if (n == 3) {  62         for(int i=0;i<n/2+1;i++)  63             for (int j = 0; j < n / 2 + 1; j++) {  64               65             result.nums[i][j]= result00.nums[i][j];  66             result.nums[i][j+n/2+1] = result01.nums[i][j];  67             result.nums[i+n/2+1][j] = result10.nums[i][j];  68             result.nums[i+n/2+1][j+n/2+1] = result11.nums[i][j];  69             }  70         }  71   72         for(int i=0;i<n/2;i++)  73             for (int j = 0; j < n / 2; j++) {  74               75             result.nums[i][j]= result00.nums[i][j];  76             result.nums[i][j+n/2] = result01.nums[i][j];  77             result.nums[i+n/2][j] = result10.nums[i][j];  78             result.nums[i+n/2][j+n/2] = result11.nums[i][j];  79             }  80   81     }  82     return result;  83 }

 

四,防止size%2!=0的处理函数(即矩阵的行列数为奇数)

 1 void matrix::matrixmultiinit(matrix &a, matrix &b) {   2    3     if (a.nums.size() % 2 != 0)   4     {   5         for (int i = 0; i < a.nums.size(); i++)   6             a.nums[i].push_back(0);   7         for (int i = 0; i < b.nums.size(); i++)   8             b.nums[i].push_back(0);   9         a.nums.push_back(*new vector<int>(a.nums[0].size(), 0));  10         b.nums.push_back(*new vector<int>(b.nums[0].size(), 0));  11         a.size++;  12         b.size++;  13     }  14 }

 

五,输出函数(这个读者随意)

 1 void matrix::display()   2 {   3     for (int i = 0; i < this->nums.size(); i++) {   4    5         cout << "||";   6         for (int j = 0; j < this->nums[i].size(); j++) {   7             cout << this->nums[i][j] << " ";   8         }   9         cout << "||" << endl;  10   11     }  12 }

 

六,测试函数

 1 #include <iostream>   2 #include"matrix.h"   3 int main()   4 {   5     vector<vector<int>> input = {    6         {1,2,3},   7         {1,2,3},   8         {1,1,1},   9     };  10     matrix test0 = * new matrix(input);  11     matrix test1 = * new matrix(input);  12     matrix test2;  13     test2.matrixmultiinit(test0, test1);  14     test2= test2.matrixmulti(test0, test1);  15     test2.display();  16   17 }

 

本人比较愚笨,耗时一天半才完成,不知道是不是天气热的原因,人太燥了,沉不下心来思考bug。

 

a*b有一点需要注意的是分块的逻辑应该怎么表示,一开始我用了两个顶点来表示一个矩阵的分块,如图:

【算法导论】--分治策略Strassen算法(运用下标运算)【c++】

然后halfsize还得一个一个的算,然后自己敲错的几率还会加大,并且还不一定表示正确每个分块,然后就逼疯自己了。

感觉这两天被这一堆bug都弄自闭了。。。。

幸好还是撑过来了,这算是我啃算法导论的第一个坎吧。

幸好第二天在csdn里面看到了别人怎么分块的。看到了一个变量halfsize,于是才开始改自己matrix的构造。

虽然一开始不愿意,但是改完之后,竟然一次过了!woc!

给我了一个教训,以后能“少”一个变量尽量“少”一个变量。

 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/602467.html

(0)
上一篇 2021年5月11日
下一篇 2021年5月11日

精彩推荐