7-2 破译报文 (PTA 字符串实验)

这篇具有很好参考价值的文章主要介绍了7-2 破译报文 (PTA 字符串实验)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

7-2 破译报文

分数 80

作者 朱允刚

单位 吉林大学

小明接到一个破解报文的任务:该报文是一串文本,破解出的密文应是在报文串中出现次数大于1的所有子串中的最长者。规定报文本身不能称为自己的子串。请编写效率尽可能高的程序帮小明完成这个棘手的任务。

输入格式:

输入为一个字符串,表示报文,包含不超过10000个字母。

输出格式:

输出为一个整数,表示破解出的密文串的长度。

输入样例1:

xabceabcf

输出样例1:

3

具体算法如下:

  1. 首先定义一个哈希函数Hash,用于计算字符串的哈希值。哈希值的计算采用了前缀哈希的方式,使用了一个预先设定的质数k和一个模数mod。对于字符串中的每个位置,计算其前缀和的哈希值。

    字符串前缀哈希法,把字符串变成一个p进制数字(哈希值),实现不同的字符串映射到
    如 X1X2X3⋯Xn−1Xn 的字符串,采用字符的ascii 码乘上 P 的次方来计算哈希值。相当于将字符串看做一个 P 进制的数字,每个位上的数字值为 ascil码的值。其中  代表  的  次方 

                7-2 破译报文 (PTA 字符串实验),哈希算法,散列表,算法                   
    s为前缀和数组,str为字符串数组        
    前缀和公式  7-2 破译报文 (PTA 字符串实验),哈希算法,散列表,算法
    区间和公式  7-2 破译报文 (PTA 字符串实验),哈希算法,散列表,算法 

  2. 定义一个辅助函数check,用于检查长度为x的子串是否在报文串中出现了多次。该函数使用一个哈希表st来记录已经出现过的子串的哈希值。遍历报文串的所有长度为x的子串,计算其哈希值并判断是否在哈希表中已经存在。如果存在,则说明该子串出现了多次,返回true;否则,将该子串的哈希值添加到哈希表中,并继续遍历下一个子串。最后,如果没有找到重复出现的子串,则返回false。使用前缀和,我们可将查询一个子串的哈希值的时间缩减为。

  3. 主函数solve中,首先读入报文串并计算其长度。然后,使用前缀哈希的方式计算字符串的哈希值,并保存在数组s中。同时,计算每个位置的权值p。接下来,使用二分查找的方式找到报文串中出现次数大于1的所有子串中的最长者。初始时,将左边界l设为0,右边界r设为报文串的长度。我们不难看出,答案是具有单调性质的。如果长度为  的子串能被找出两次以上,那么长度为 的子串也能被找出两次以上。

  4. 时间复杂度 ,空间复杂度文章来源地址https://www.toymoban.com/news/detail-715485.html

    #define int long long
    #define endl '\n'
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rep(a, b, c) for (a = b; a <= c; a++)
    using namespace std;
    
    typedef long long ll;
    typedef double db;
    typedef pair<int,int> pii;
    const int N = 10010, mod = 1e9 + 7;
    
    int k = 100007;
    char str[N];
    int s[N],p[N];
    int n;
    unordered_map <int,bool> st;
    
    int Hash(int l,int r){
        int t = (s[r] - (s[l-1] * p[r-l+1] % mod) + mod) % mod;
        return t;
    }
    
    bool check(int x){
        int i;
        st.clear();
        
        rep(i,1,n-x+1){
            int t = Hash(i,i+x-1);
            // cout << ' ' << i << ' ' << i+x-1 <<" HASH is " << t << endl;
    
            if (st[t]) return 1;
            st[t] = 1;
        }
        return 0;
    }
    
    void solve(){
        cin >> str+1;
        n = strlen(str+1);
    
        int i;
        
        p[0] = 1;
        rep(i,1,n){
            s[i] = (s[i-1] * k + str[i]) % mod;
            p[i] = p[i-1] * k % mod;
        }   
    
        int l = 0,r = n;
    
        while (l + 1 != r){
            int mid = l + r >> 1;
            if (check(mid)){
                l = mid;
            }else{
                r = mid;
            }
        }
    
        cout << l << endl;
    }
    

到了这里,关于7-2 破译报文 (PTA 字符串实验)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PTA:使用函数实现字符串部分复制(C)

    本题要求编写函数,将输入字符串t中从第m个字符开始的全部字符复制到字符串 s 中。 函数接口定义: 函数 strmcpy 将输入字符串 char *t 中从第 m 个字符开始的全部字符复制到字符串 char *s 中。若 m 超过输入字符串的长度,则结果字符串应为空串。 裁判测试程序样例: 输入样

    2024年02月02日
    浏览(31)
  • PTA C语言 7-1 删除字符串中指定字母

    请使用指针的方法编写程序,程序的功能是从键盘输入一个字符串(字符串长度小于100),删除其中的字母a后输出。例如,输入字符串abcaca,输出bcc。 输入样例: 输出样例: 答案:   数组实际上就是指针,所有没有问题 因为

    2024年02月03日
    浏览(59)
  • 哈希表+字符串

    一)知识回顾: 1)哈希表是什么?哈希表是存储数据的容器 2)哈希表有啥用?快速的查找某一个元素 3)什么时候使用哈希表?频繁的查找某一个数的时候, 当我们快速查找某一个数的时候,不光要想到哈希表还需要想到二分查找,但是二分查找算法的局限性太强了,必须数组中有序

    2024年02月10日
    浏览(35)
  • 2023-8-26 字符串哈希

    题目链接:字符串哈希

    2024年02月11日
    浏览(37)
  • 字符串中的BKDRHash哈希函数

    在计算机科学中,哈希函数是一种将任意长度的输入(也称为“消息”)通过散列算法转换成固定长度的输出,该输出就是哈希值。哈希函数的一个重要特性是,对于相同的输入,无论何时执行哈希函数,它都应该产生相同的输出。然而,对于不同的输入,即使它们只有微小

    2024年02月08日
    浏览(73)
  • LeetCode 2744.最大字符串配对数目:哈希表

    力扣题目链接:https://leetcode.cn/problems/find-maximum-number-of-string-pairs/ 给你一个下标从 0  开始的数组  words  ,数组中包含 互不相同  的字符串。 如果字符串  words[i]  与字符串 words[j]  满足以下条件,我们称它们可以匹配: 字符串  words[i]  等于  words[j]  的反转字符串。 0

    2024年01月22日
    浏览(44)
  • 438. 找到字符串中所有字母异位词【异位词-哈希数组】

    438. 找到字符串中所有字母异位词 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。 示例 1: 输入: s = “cbaebabacd”, p = “abc” 输出: [0,6] 解释: 起

    2023年04月27日
    浏览(40)
  • LeetCode-763. 划分字母区间【贪心 哈希表 双指针 字符串】

    给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。 注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。 示例 1: 输入:s = “ababcbacadefegdehijhklij” 输

    2024年04月10日
    浏览(56)
  • cf edu152 C. Binary String Copying(字符串双哈希)

    cf edu152 C. Binary String Copying(字符串双哈希) 题目链接:https://codeforces.com/contest/1849/problem/C 题目大意 给定一个01字符串,长度为n,拷贝m份,对每一份进行相应操作:将 [ L i , R i ] [L_i,R_i] [ L i ​ , R i ​ ] 的字符排序,实际就是调整为0在前1在后,问得到的m个副本有多少个不同

    2024年02月15日
    浏览(37)
  • rust踩雷笔记(2)——一道hard带来的思考[哈希表、字符串、滑动窗口]

    今天被一道hard恶心坏了,算法不难,用C++几分钟的事。用rust主要还是缺乏对语言的熟练度,记录一下,主要的坑在下面这个操作: 对String取其中某个位置的char。 可能你会有疑问:这不是直接nth()取就行了么。没错,我看有些题解也是这样做的,但是那样会在某些字符长度很

    2024年02月12日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包