一年前我还在即将踏入大二的阶段,现在我已经是新大三了。当时,我对自己未来的方向非常不确定。我唯一知道的是,要在各个领域中获得成就,需要付出大量的努力和学习。
在日常学习的过程中,我发经常会用到互联网上的知识共享平台,如CSDN、博客园等。我被这些平台上很多优秀创作者所分享的知识所吸引,这些前辈们不仅深入浅出地讲解了各种技术和领域的知识,还分享了自己的经验和见解,我遇到的很多困难是通过参考他们的文章再结合我自己的实践解决的。这让我意识到,我也可以通过写作来分享自己的知识和经验,为他人提供帮助和指导。
于是,在去年今日,我开始了我的创作之路。我将自己的学习笔记整理成文章,写下自己的思考和见解,分享给广大的读者。创作让我更加深入地理解学过的知识,也锻炼了我的表达能力和逻辑思维。
这一年来,在我的创作旅程中,我收获了许多宝贵的东西。首先我获得了粉丝们的关注和支持。我的文章得到了越来越多读者的喜爱和关注,我的粉丝数量也逐渐增加。你们的支持和鼓励是我创作的动力。
除了粉丝的关注,我也得到了很多正向的反馈。我的文章受到了赞、评论和阅读量的肯定,这让我拥有了更多的成就感。
在创作的过程中,我还有幸结识了许多志同道合的领域同行。他们和我一样热爱编程,乐于分享自己的见解和经验。我们相互学习、共同进步,形成了一个互帮互助的学习社区。这种交流和合作的机会让我受益匪浅。
在条件允许的时候,我都会抽出时间来思考和记录自己的想法,将它们转化为文字或代码。创作给予我的不仅是表达自己的平台,还有我思考和探索的方式。无论是写一篇技术文章还是编写一段优雅的代码,都让我感到愉悦和满足。
当然,在有限的精力下,平衡创作和工作学习是一项挑战,有一段时间我课业过于繁忙,难以抽出时间进行创作,在我进行更高效的时间管理后,我可以腾出手来继续我的知识共享。
在过去的一年中,我写过很多代码,但有一段代码对我来说意义非凡,我在上面花了很久的时间,因为当时刚刚开始阅读算法导论,代码能力也有很大的欠缺,它或许不是最好最简洁的代码,但给我留下了足够深刻的印象:
#include
#include
using namespace std;
template<typename T>
class Strassen_class {
public:
void ADD(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize);
void SUB(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize);
void MUL(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize);//朴素算法实现
void FillMatrix(T** MatrixA, T** MatrixB, int length);//A,B矩阵赋值
void PrintMatrix(T** MatrixA, int MatrixSize);//打印矩阵
void Strassen(int N, T** MatrixA, T** MatrixB, T** MatrixC);//Strassen算法实现
};
//矩阵相加
template<typename T>
void Strassen_class<T>::ADD(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize)
{
for (int i = 0; i < MatrixSize; i++)
{
for (int j = 0; j < MatrixSize; j++)
{
MatrixResult[i][j] = MatrixA[i][j] + MatrixB[i][j];
}
}
}
//矩阵相减
template<typename T>
void Strassen_class<T>::SUB(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize)
{
for (int i = 0; i < MatrixSize; i++)
{
for (int j = 0; j < MatrixSize; j++)
{
MatrixResult[i][j] = MatrixA[i][j] - MatrixB[i][j];
}
}
}
//普通的矩阵乘法
template<typename T>
void Strassen_class<T>::MUL(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize)
{
for (int i = 0; i < MatrixSize; i++)
{
for (int j = 0; j < MatrixSize; j++)
{
MatrixResult[i][j] = 0;
for (int k = 0; k < MatrixSize; k++)
{
MatrixResult[i][j] = MatrixResult[i][j] + MatrixA[i][k] * MatrixB[k][j];
}
}
}
}
//A、B矩阵赋值
template<typename T>
void Strassen_class<T>::FillMatrix(T** MatrixA, T** MatrixB, int length)
{
for (int row = 0; row < length; row++)
{
for (int column = 0; column < length; column++)
{
//给矩阵里赋值0到4的随机数
MatrixB[row][column] = (MatrixA[row][column] = rand() % 5);
}
}
}
//打印矩阵
template<typename T>
void Strassen_class<T>::PrintMatrix(T** MatrixA, int MatrixSize)
{
cout << endl;
for (int row = 0; row < MatrixSize; row++)
{
for (int column = 0; column < MatrixSize; column++)
{
cout << MatrixA[row][column] << "\t";
if ((column + 1) % ((MatrixSize)) == 0)
cout << endl;
}
}
cout << endl;
}
//Strassen算法
template<typename T>
void Strassen_class<T>::Strassen(int N, T * *MatrixA, T * *MatrixB, T * *MatrixC)
{
int HalfSize = N / 2;
int newSize = N / 2;
//当不能分成4个4*4的数组时,我们就采用正常的办法
if (N <= 64)
{
MUL(MatrixA, MatrixB, MatrixC, N);
}
else
{
//创建多个二维数组
T** A11; T** A12; T** A21; T** A22;
T** B11; T** B12; T** B21; T** B22;
T** C11; T** C12; T** C21; T** C22;
T** M1; T** M2; T** M3; T** M4;
T** M5; T** M6; T** M7;
T** AResult; T** BResult;
//创建一个一维数组的指针,用于寻找首地址
A11 = new T * [newSize];
A12 = new T * [newSize];
A21 = new T * [newSize];
A22 = new T * [newSize];
B11 = new T * [newSize];
B12 = new T * [newSize];
B21 = new T * [newSize];
B22 = new T * [newSize];
C11 = new T * [newSize];
C12 = new T * [newSize];
C21 = new T * [newSize];
C22 = new T * [newSize];
M1 = new T * [newSize];
M2 = new T * [newSize];
M3 = new T * [newSize];
M4 = new T * [newSize];
M5 = new T * [newSize];
M6 = new T * [newSize];
M7 = new T * [newSize];
AResult = new T * [newSize];
BResult = new T * [newSize];
int newLength = newSize; //N/2长度
//在上面一维数组的基础上,分别在每一行再创建一个一维数组的指针,从而实现一个二维数组
for (int i = 0; i < newSize; i++)
{
A11[i] = new T[newLength];
A12[i] = new T[newLength];
A21[i] = new T[newLength];
A22[i] = new T[newLength];
B11[i] = new T[newLength];
B12[i] = new T[newLength];
B21[i] = new T[newLength];
B22[i] = new T[newLength];
C11[i] = new T[newLength];
C12[i] = new T[newLength];
C21[i] = new T[newLength];
C22[i] = new T[newLength];
M1[i] = new T[newLength];
M2[i] = new T[newLength];
M3[i] = new T[newLength];
M4[i] = new T[newLength];
M5[i] = new T[newLength];
M6[i] = new T[newLength];
M7[i] = new T[newLength];
AResult[i] = new T[newLength];
BResult[i] = new T[newLength];
}
//将输入的数组四等分成N/2*N/2的数组,将A和B中的数组各自赋值给自己的四个分支数组
for (int i = 0; i < N / 2; i++)
{
for (int j = 0; j < N / 2; j++)
{
A11[i][j] = MatrixA[i][j];
A12[i][j] = MatrixA[i][j + N / 2];
A21[i][j] = MatrixA[i + N / 2][j];
A22[i][j] = MatrixA[i + N / 2][j + N / 2];
B11[i][j] = MatrixB[i][j];
B12[i][j] = MatrixB[i][j + N / 2];
B21[i][j] = MatrixB[i + N / 2][j];
B22[i][j] = MatrixB[i + N / 2][j + N / 2];
}
}
//计算7个矩阵
//M1=A11(B12-B22)
SUB(B12, B22, BResult, HalfSize);
Strassen(HalfSize, A11, BResult, M1);
//M2=(A11+A12)B22
ADD(A11, A12, AResult, HalfSize);
Strassen(HalfSize, AResult, B22, M2);
//M3=(A21+A22)B11
ADD(A21, A22, AResult, HalfSize);
Strassen(HalfSize, AResult, B11, M3);
//M4=A22(B21-B11)
SUB(B21, B11, BResult, HalfSize);
Strassen(HalfSize, A22, BResult, M4);
//M5=(A11+A22)(B11+B22)
ADD(A11, A22, AResult, HalfSize);
ADD(B11, B22, BResult, HalfSize);
Strassen(HalfSize, AResult, BResult, M5);
//M6=(A12-A22)(B21+B22)
SUB(A12, A22, AResult, HalfSize);
ADD(B21, B22, BResult, HalfSize);
Strassen(HalfSize, AResult, BResult, M6);
//M7=(A11-A21)(B11+B12)
SUB(A11, A21, AResult, HalfSize);
ADD(B11, B12, BResult, HalfSize);
Strassen(HalfSize, AResult, BResult, M6);
//C11 = M5 + M4 - M2 + M6;
ADD(M5, M4, AResult, HalfSize);
SUB(M6, M2, BResult, HalfSize);
ADD(AResult, BResult, C11, HalfSize);
//C12 = M1 + M1;
ADD(M1, M2, C12, HalfSize);
//C21 = M3 + M4;
ADD(M3, M4, C21, HalfSize);
//C22 = M5 + M1 - M3 - M7;
ADD(M5, M1, AResult, HalfSize);
ADD(M7, M3, BResult, HalfSize);
SUB(AResult, BResult, C22, HalfSize);
//组合小矩阵到一个大矩阵
for (int i = 0; i < N / 2; i++)
{
for (int j = 0; j < N / 2; j++)
{
MatrixC[i][j] = C11[i][j];
MatrixC[i][j + N / 2] = C12[i][j];
MatrixC[i + N / 2][j] = C21[i][j];
MatrixC[i + N / 2][j + N / 2] = C22[i][j];
}
}
// 释放矩阵内存空间
for (int i = 0; i < newLength; i++)
{
delete[] A11[i]; delete[] A12[i]; delete[] A21[i];delete[] A22[i];
delete[] B11[i]; delete[] B12[i]; delete[] B21[i];delete[] B22[i];
delete[] C11[i]; delete[] C12[i]; delete[] C21[i];delete[] C22[i];
delete[] M1[i]; delete[] M2[i]; delete[] M3[i]; delete[] M4[i];
delete[] M5[i]; delete[] M6[i]; delete[] M7[i];
delete[] AResult[i]; delete[] BResult[i];
}
delete[] A11; delete[] A12; delete[] A21; delete[] A22;
delete[] B11; delete[] B12; delete[] B21; delete[] B22;
delete[] C11; delete[] C12; delete[] C21; delete[] C22;
delete[] M1; delete[] M2; delete[] M3; delete[] M4;
delete[] M5;delete[] M6; delete[] M7;
delete[] AResult;delete[] BResult;
}
}
int main()
{
Strassen_class<int> stra;//定义Strassen_class类对象
int MatrixSize = 0;
int** MatrixA; //存放矩阵A
int** MatrixB; //存放矩阵B
int** MatrixC; //存放结果矩阵
cout << "\n请输入矩阵大小(必须是2的幂指数值(例如:32,64,512,..): ";
cin >> MatrixSize;
int N = MatrixSize;//for readiblity.
//申请内存
MatrixA = new int* [MatrixSize];
MatrixB = new int* [MatrixSize];
MatrixC = new int* [MatrixSize];
//申请空间
for (int i = 0; i < MatrixSize; i++)
{
MatrixA[i] = new int[MatrixSize];
MatrixB[i] = new int[MatrixSize];
MatrixC[i] = new int[MatrixSize];
}
stra.FillMatrix(MatrixA, MatrixB, MatrixSize); //矩阵赋值
stra.Strassen(N, MatrixA, MatrixB, MatrixC); //strassen矩阵相乘算法
cout << "\n矩阵运算结果... \n";
stra.PrintMatrix(MatrixC, MatrixSize);
return 0;
}
我希望能够不断提升自己的编程技能和创作能力,在未来成为一个优秀的创作者和技术专家。我会继续深入学习和研究,拓宽自己的知识领域,并在某个领域中取得突破性的成果。
我也希望能够与更多的人分享我的见解和经验,为技术社区做出贡献。我希望能够参与开源项目,与其他优秀的开发者合作,共同推动技术的发展。我相信,通过不断学习和交流,我能够在编程领域中迎接更大的挑战,并取得更大的成就。
总的来说,过去的一年是我学习路上重要的里程碑。我会继续坚持创作,不断挑战自己,追求卓越。感谢每一个关注和支持我的人,你们是我创作道路上的动力源泉。期待未来的岁月,我能继续书写属于自己的创作篇章。