文章目录
前言
很忙,不写前言
一、求矩阵(二维数组存储)乘积算法Multi1
实现功能
求矩阵A[m][p]与B[p][n]的乘积
ADL描述
实现
vector<vector<int>> Multi1(vector<vector<int>> A,vector<vector<int>> B) {
int m = A.size(), p = A[0].size() , n = B[0].size();
vector<vector<int>> C(m, vector<int>(n));
for(int i=0;i<m;i++)
for (int j = 0; j < n; j++)
{
for (int k = 0; k < p; k++)
{
C[i][j] += A[i][k] * B[k][j];
}
}
return C;
}
二、求矩阵(一维数组存储)乘积算法Multi2
实现功能
同上,但结果与运算数由一维数组存储
ADL描述
实现
vector<int> Multi2(vector<int> A, vector<int> B,int m,int p,int n) {
vector<int> C(m*n,0);
int cw = 0;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
int cs = i * p;
int ct = j;
for (int k = 0; k < p; k++)
{
C[cw] += A[cs] * B[ct];
cs++;
ct += n;
}
cw++;
}
return C;
}
--------------三元组与十字链表类----------------
struct Node {//三元组节点
int row;
int col;
int value;
};
struct CrossNode {//十字链表节点
int row;
int col;
int value;
CrossNode* left;
CrossNode* up;
};
void print_Node(vector<Node> a) {//打印三元组表
for (auto aa : a)
{
cout << aa.col << " " << aa.row << " " << aa.value << endl;
}
return;
}
三、三元组矩阵转置transpose
实现功能
求A的转置矩阵并将其保存在三元组表b中
ADL描述
实现
vector<Node> Transpose(vector<Node> a,int maxcol) {
vector<Node> b(a.size());
int j = 0;
for(int k=0;k<=maxcol;k++)
for (int i = 0; i < a.size(); i++)
{
if (a[i].col == k)
{
b[j].col = a[i].row;
b[j].row = k;
b[j].value = a[i].value;
j++;
}
}
return b;
}
四、复制字符串strcpy
实现功能
将字符串s复制到字符串p
ADL描述
实现
string Strcpy(string s) {
int i = 0;
string p;
p.resize(s.length());
while (s[i] != '\0')
{
p[i]=s[i];
i++;
}
p[i] = '\0';
return p;
}
五、朴素的模式匹配算法StringMatching
实现功能
返回S中首个P子串的位置
ADL描述
]
实现
int StringMatching(string S, string P) {
int i = 0;
while (i <= S.size() - P.size())
{
int j = 0;
while (S[i] == P[j] && j < P.size())
{
i++;
j++;
}
if (j == P.size())return i - j;
i = i - j + 1;
}
return -1;
}
六、KMP算法
实现功能
返回S中首个P子串的位置
ADL描述
实现(与失败函数求解打包)
int KMP(string S,string P) {
int n = S.size(), m = P.size();
vector<int> fail(m, -1);
for (int j = 1; j < m; j++)
{
int i = fail[j - 1];//i为j前位置应跳转到的元素
while (P[i + 1] != P[j] && i >= 0)i = fail[i];//i后元素一旦不与j的相同,一直取fail直到相同或-1
if (P[i + 1] == P[j])fail[j] = i + 1;//如果是因相等而退出的,说明应退回到i+1
else fail[j] = -1;
}
int i = 0, j = 0;//i目标串,j模式串
while (i < n && j < m)
{
if (P[j] == S[i])//每次检查是ij指向的元素否匹配
{
i++;
j++;
}
else
{
if (j == 0)i++;//首个不匹配,j无需移动,i后移
else j = fail[j-1]+1;//不是首个,j取到其前一个元素的跳转值+1
}
}
if (j < m)return -1;//若结束后j仍<m,说明i已遍历完成,且没有匹配元素
else return i - m;//否则返回首个匹配结束位置-模式长
}
七、KMP算法plus版
实现功能
返回S中模式串P的个数
自己写的,没有ADL描述
在匹配成功后,为了继续搜寻模式串,让模式串指针j跳转到失败函数位置即可
实现(与失败函数求解打包)
int KMP(string S, string P) {
int n = S.size(), m = P.size(),sum=0;
vector<int> fail(m, -1);
for (int j = 1; j < m; j++)
{
int i = fail[j - 1];//i为j前位置应跳转到的元素
while (P[i + 1] != P[j] && i >= 0)i = fail[i];//i后元素一旦不与j的相同,一直取fail直到相同或-1
if (P[i + 1] == P[j])fail[j] = i + 1;//如果是因相等而退出的,说明应退回到i+1
else fail[j] = -1;
}
int i = 0, j = 0;//i目标串,j模式串
while (i < n)
{
if (P[j] == S[i])//每次检查是ij指向的元素否匹配
{
if (j == m - 1)
{
j = fail[j - 1] + 1;//匹配,j回退
sum++;
continue;
}
i++;
j++;
}
else
{
if (j == 0)i++;//首个不匹配,j无需移动,i后移
else j = fail[j - 1] + 1;//不是首个,j取到其前一个元素的跳转值+1
}
}
return sum;//返回模式串个数
}
测试用例
int main()
{
vector<int> a = { 1,2,3,2,4,5,6,1,7,8,9,3 };
vector<int> b = { 3,2,1,6,5,4,9,8,7,1,2,3 };
vector<vector<int>> A =
{ {1,2,3,2},
{4,5,6,1},
{7,8,9,3}, };
vector<vector<int>> B =
{ {3,2,1},
{6,5,4},
{9,8,7},
{1,2,3} };
auto ans1 = Multi1(A,B);
auto ans2 = Multi2(a, b, 3, 4, 3);
for (int i = 0; i < ans2.size(); i++)cout << ans2[i]<<" ";
cout << endl;
for(int i=0;i<ans1.size();i++)
for (int j = 0; j < ans1[0].size(); j++)
{
cout << ans1[i][j]<<" ";
if (j == ans1[0].size() - 1)cout << endl;
}
vector<Node> TGL(2);//三元组表
TGL[0].col = 4; TGL[0].row = 1; TGL[0].value = 114;
TGL[1].col = 2; TGL[1].row = 3; TGL[1].value = 514;
print_Node(TGL);
auto TGL2=Transpose(TGL,4);
print_Node(TGL2);
string name = "cualb";
cout << Strcpy(name) << endl;
cout << StringMatching("xbcualbavl", "cualb") << endl;
cout << KMP("aaaabbaabb", "baabb");
}
总结
很忙,不写总结