课内学习笔记二

news/2025/3/9 19:02:57/文章来源:https://www.cnblogs.com/cai-cai-zi/p/18761187

快1个小时写了一个分治方法求解矩阵的算法,最后的结果还没运行出来,还是靠Deepseek才检查出来的问题,
DeepSeek用了不到30s就给出了答案,再一次感到挫败感,但是如果是搜索引擎查找copy的话,也是是和AI解答
一样,失去了练手和增加写代码能力的机会,所以无需自责,只是锻炼自己的能力罢了。

分治法求解矩阵

普通递归分块矩阵解决

主体思想是,把一个2^n次方阶数的矩阵,逐步细分,每次递归按照n/2逐步划分,直到n/2变成1*1的时候直接
返回成{{A[0][0]*B[0][0]}}的二维数组,为什么返回的是二维数组呢?我刚开始没想通,就理所当然的认为
必须返回个二维数组,但是我写这篇文章的时候又细想了一下,分治的思想是逐步缩小规模,原始规模是一个二维
数组的矩阵,所以缩小规模到维数为1维,也就是A[0][0]一个元素时,相当于一个值,计算与B[0][0]相乘后,获得
的是一个值,但是我们要把它看作一个1*1维的矩阵,因为这只是一个中间步骤,逐步划分,是要求划分后的C11,
C11=A11*B11+A12*B21。
当我们逐步缩小规模到2*2矩阵时,此时A11是2*2矩阵左上角的1维元素,同理其他的,
现在算C11,C11=M(A11,A12)+M(A12,A21),先进入第一个M,再次划分,变成1*1维的,这时不再划分A11,A12...
直接返回,比如{{0}},同理再求第二个M,然后比如返回{{1}},相加后{{1}},是C11也就是二维的左上角的二维矩阵
同理C12,C21,C22,然后再统一按二维数组的遍历去组装C,然后返回,这个实际上二维的矩阵就返回成功了。
更多维的比如4维,8维,还是同样的思路,但是都是深入到底层,然后逐渐返回上来。
像这种递归,分治的这种算法,如果处处都深入分析,那么还不如去循环,掌握它的每一处,递归只要注意到
界限条件和缩小的情况,然后胆大地去写


时间复杂度是8(n/2)+Θ(n2),8(n/2)是划分了8个规模缩小1/2的递归,n2是矩阵相加
master方法求解后时间复杂度的n^3

几个编程注意的点:

  1. {{A[0][0]*B[0][0]}},这种是初始化列表,return返回这个列表时,如果返回值是数组就会赋给数组,如果
    返回给vector就会初始化vector

  2. 在编程时吃了C++11,初始化列表的大苦头。

  vector<int> v1(10);  // 10个元素的vectorvector<int> v2{10};  // 1个元素(值为10)//vector如果使用{}统一初始化作为构造函数时,会调用有初始化列表的构造函数//要显式调用某个构造函数的话还是使用()尽管会有隐式转换等问题struct Data {Data(int) {}Data(std::initializer_list<double>) {}};Data d(5);  // 调用Data(int)Data d{5};  // 调用initializer_list(优先匹配)
  1. vector<vector> C11 = matrixAdd(matrixMultiply(A11,B11),matrixMultiply(A12,B21));
    这里直接使用matrixMultiply(xxx)函数的返回值作为参数,这里是直接返回的右值,也就是临时值,我之前
    的函数参数是vector<vector>& A,没加const,编译器会报错的,不能将右值直接赋给没加const的引用

C++代码

#include<iostream>
#include<vector>using namespace std;vector<vector<int>> matrixAdd(const vector<vector<int>>&s1,const vector<vector<int>>&s2){int length = s1.size();vector<vector<int>> s3{length,vector<int>{length,0}};for(int i=0;i<length;i++){for(int j=0;j<length;j++){s3[i][j]=s1[i][j]+s2[i][j];}}return s3;
} void matrixPrint(const vector<vector<int>>& s){for(int i=0;i<s.size();i++){cout<<"[ ";for(int j=0;j<s.size();j++){cout<<s[i][j]<<" ";}cout<<"]"<<endl;}	
}vector<vector<int>> matrixMultiply(const vector<vector<int>>&A,const vector<vector<int>>&B){int length = A.size()/2;if(A.size()==1){return {{A[0][0]*B[0][0]}};}vector<vector<int>> A11(length,vector<int>(length,0));vector<vector<int>> A12(length,vector<int>(length,0));vector<vector<int>> A21(length,vector<int>(length,0));vector<vector<int>> A22(length,vector<int>(length,0));vector<vector<int>> B11(length,vector<int>(length,0));vector<vector<int>> B12(length,vector<int>(length,0));vector<vector<int>> B21(length,vector<int>(length,0));vector<vector<int>> B22(length,vector<int>(length,0));for(int i=0;i<length;i++){for(int j=0;j<length;j++){//修改左侧A11-B22的下标全部变成[i][j] A11[i][j]=A[i][j];A12[i][j]=A[i][j+length];A21[i][j]=A[i+length][j];A22[i][j]=A[i+length][j+length];B11[i][j]=B[i][j];B12[i][j]=B[i][j+length];B21[i][j]=B[i+length][j];B22[i][j]=B[i+length][j+length];}}vector<vector<int>> C11 = matrixAdd(matrixMultiply(A11,B11),matrixMultiply(A12,B21));vector<vector<int>> C12 = matrixAdd(matrixMultiply(A11,B12),matrixMultiply(A12,B22));vector<vector<int>> C21 = matrixAdd(matrixMultiply(A21,B11),matrixMultiply(A22,B21));vector<vector<int>> C22 = matrixAdd(matrixMultiply(A21,B12),matrixMultiply(A22,B22));vector<vector<int>> C(A.size(),vector<int>(A.size(),0));for(int i=0;i<length;i++){for(int j=0;j<length;j++){C[i][j]=C11[i][j];C[i][j+length]=C12[i][j];C[i+length][j]=C21[i][j];C[i+length][j+length]=C22[i][j];}}return C;
}int main(){vector<vector<int>> A{{1,2,3,4},{1,2,3,4},{2,1,3,4},{2,2,3,4}};vector<vector<int>> B{{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};vector<vector<int>> C = matrixMultiply(A,B);matrixPrint(C);return 0;
}

Strassen's method求解矩阵乘法

主要思想是通过加法去减少乘法的次数
步骤就去BaiDu好了,这里时间复杂度是O(nlog27)

用了近2个小时,时间效率好低,这才只是开始啊,好想回到大一,那个时候几乎有打吧的时间(可能现在这么认为),但是
回不到过去,只能现在做到最好

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/896037.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【每日一题】20250309

我所渴望的,不过是过上一种发自本心的生活,为什么竟会如此困难?【每日一题】已知 \(\odot C\) 过点 \(P(1,2)\),与 \(y\) 轴相交于点 \(Q(0,6)\).若过点 \(Q\) 作 \(\odot C\) 的切线 \(l\),其切线 \(l\) 与 \(x\) 轴平行,则 \(l\) 的方程为_________,\(\odot C\) 的标…

FastAPI Cookie 和 Header 参数完全指南:从基础到高级实战

title: FastAPI Cookie 和 Header 参数完全指南:从基础到高级实战 🚀 date: 2025/3/9 updated: 2025/3/9 author: cmdragon excerpt: 本教程深入探讨 FastAPI 中 Cookie 和 Header 参数的读取与设置,涵盖从基础操作到高级用法。通过详细的代码示例、课后测验和常见错误解…

vim按f5运行代码配置

使vim能够像vscode一样按f5运行代码 效果图let g:last_terminal_buf = -1 " 用于存储上一个终端缓冲区编号 function! RunCurrentFile() " 如果存在上次的终端缓冲区,则删除它 if g:last_terminal_buf != -1 && bufexists(g:last_terminal_buf) silent exec…

DeepSeek + Xmind,1分钟自动把pdf/word文档转成思维导图

DeepSeek加Xmind,1分钟把PDF、Word文档转成思维导图!步骤超简单:第一步:打开DeepSeek,点击“深度思考”,上传你的文档。第二步:告诉DeepSeek“帮我转成思维导图,输出Markdown格式”。第三步:复制代码, 保存文件到桌面文本文件中,修改文件后缀为“.md”。第四步:打开…

Windows平台调试器原理与编写05.内存断点

https://www.bpsend.net/thread-274-1-3.html 内存断点访问断点 写入断点内存写入断点简介:当被调试进程访问,读或写指定内存的时候,程序能够断下来。 思考1:要想将一段内存设为内存断点,最终的目的是让其能够抛异常。调试器是基于异常的一个程序。应该如何实现呢?可以通…

Redis--Lesson01--NoSQL简史

单击MySQL的演进 单机MySQL 在早期互联网时代,也就是90年代以前,一个基本的互联网的访问量不会太大,可以说很多国家和地区都还没有配备互联网,所以在这种情况下的互联网格局使用的数据存储格式就是简单的单机模式,即使用一个数据库的如MySQL库就可以满足日常的数据读写 如…

Excel的快捷键

1、填充序号1~1000(删除后,序号会自动更新) (1)首先在左上角的位置框中输入A1:A1000,然后按Enter回车健,即可选中A1到A1000的单元格。(2)然后在函数框中输入=ROW(),按Ctrl + Enter即可,即可填充1-1000。 本文来自博客园,作者:业余砖家,转载请注明原文链接:http…

AutoGLM: Autonomous Foundation Agents for GUIs

AutoGLM: 针对Web和手机,基于ChatGLM,具体细节并不清楚。主要内容 提出AUTOGLM,集成了一套全面的技术和基础设施,以创建适合用户交付的可部署代理系统。首先,为GUI控制设计合适的"intermediate interface"是至关重要的,可以实现规划和定位的分离。其次,开发了…

Vulnhub-election靶机

总结:本靶机给了很多目录,对于信息收集考察的比较严格,给了一个数据库,很多时候容易陷进去,拿到用户权限登录后,也需要大量的信息收集,虽然可以在数据库里找到root和密码,但是不是靶机本身的,最终利用suid发现可疑目录,查找日志后利用脚本提权一、靶机搭建 选择扫描虚…

[HDCTF 2023]double_code _wp

其实这道题的加密函数我是手翻出来的,但是做完之后了解到这是一个sheelcode 实际上就是跑病毒的代码 WriteProcessMemory 用于向指定进程中写入数据,写入一个缓冲区中的数据到另一个进程指定的内存地址中。 函数接受的参数包括要写入的进程句柄,要写入的内存地址,要写入的…

VisionPro添加显示标签(二维码)简单版

!!!——!!! 咱们先展示效果,这个显示的是二维码的信息1.首先呢,你先添加工具 CogIDTool ,工具里我是这么设置的,如果你自己添加的码跟我的不一样,左边几个都运行看看2.现在可以添加脚本了,我接触的都是第二个C#高级脚本,下边是C#高级脚本演示 1)先创建 1个标签2)…

初步学习Android studio

下载安装了Android studio,并在其中下载好了gradle,在模拟手机中实现helloworld