吉林大学大数据专业数据结构算法实现-第四章-数组和字符串


前言

很忙,不写前言


一、求矩阵(二维数组存储)乘积算法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");
}

总结

很忙,不写总结

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值