zoukankan      html  css  js  c++  java
  • 20190724 KMP

      通了个宵,还得去洗衣服,睡醒做题还时很舒服的,发现可能更适合一个人窝在寝室。

      大佬请绕,菜鸡刺猬场

      循环节......len - next[len],没有系统学过KMP的小白只能总结成,

    next记录相同前缀的尽可能后面的下标,所以next [ i ] 同时记录了是从 1 开始计算的 第几个元素前缀相同,

    也说明了前缀的数量。然后公式就很本能了。 从next [ len ] 指代的长度来源为len或者就是next [ len ] 的角

    度来看,len - next[len] 既可以后面的周期,也可以代表前面的周期。abcabcabcab,-1// 0 0 0 1 2 3 4 5 6 7 8

    11 - 8 = 3 可以是最后两个b之间的周期,也可以说是最后一个b的8个前缀之前的长度,从getnext的角度来看的

    话,只有存在某个周期,然后T之后的next才会不断增加,并且增加的速度和下标增加的速度一致。

      HDU3746

      题意 给你字符串,然后问在最后加上多少字符,可以使得整个字符串是循环的

      在最后判别加多少个的时候好像有多种判别方式这里提供两种

      

    #include <stdio.h>
    #include <string.h>
    const int maxn = 100000 +10;
    char s[maxn];
    int next[maxn];
    int len, length;
    void getnext() {
        int i=0, j = -1;
        next[0] = -1;
        while (i < len) {
            while (j != -1 && s[i] != s[j])
                j = next[j];
            next[++i] = ++j;
        }
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        while (t--){
            scanf("%s", s);
            len = strlen(s);
            getnext();
            length = len - next[len];
    //        printf("length = %d = %d - %d
    ", length, len, next[len]);
            if (len % length == 0 && len != length) {
                puts("0");
            }else {
                //1
                printf("%d
    ", (length - len % length) == 0 ? (len) : (length - len % length));
                //2 printf("%d
    ", length - next[len] % length);//next可以确定最后一个元素在上一个周期里
                //面的哪个位置,然后去掉前面的周期
            }
        }
        return 0;
    }

     HDU 2594 Simpsons’ Hidden Talents

      题意 输出尽可能长的 s1前缀与s2后缀相同的部分以及长度

      思路是第一个拿来当pattern,然后对后面的一个一个匹配,如果前一个满了,就退一次这样最后的结果是前面的尽量跟后面的后面匹配

      注意getnext从-1开始,匹配从0开始

    int solve() {
        int len1 = strlen(s1);
        int len2 = strlen(s2);
        int i = 0, j = 0;
    
        while (i < len2) {
            if (j == -1 || s1[j] == s2[i]) {
                i++;
                j++;
                if (j == len1 && i != len2) {
                    j = next[j];
                }
            }
            else
                j = next[j];
        }
        return j;
    }

      HDU 3366  Count the string

      题意 一个串 getnext过程中各个前缀遍历的总次数

      想直接统计来着 dp 永远是别人的,我什么也没有

      按照搜索的想法是要一个一个getnext下去直到 j == -1,然而,深搜不也经常dp吗?设置dp[ j ] = 从第一个字符(起点) 到 j (点) 的路径长度

    #include <stdio.h>
    #include <string.h>
    const int maxn = 200000 + 10;
    const int mod = 10007;
    char s[maxn];
    int next[maxn];
    int dp[maxn];
    int len, length;
    void getnext() {
        int i=0, j = -1;
        next[0] = -1;
        int len = strlen(s);
        while (i < len) {
            while (j != -1 && s[i] != s[j])
                j = next[j];
            next[++i] = ++j;
        }
    }
    int main()
    {
        int ans;
        int t;
        scanf("%d", &t);
        while (t--) {
            scanf("%d%s", &len, s);
            for (int i = 0; i <= len; i++)dp[i] = 0;
            getnext();
            ans = 0;
            for (int i = 1; i <= len; i++) {
                dp[i] = dp[next[i]] + 1;
                dp[i] = dp[i] % mod;
                ans = ans + dp[i];
                ans = ans % mod;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    常用Js笔记,以后可能用得上
    基于Nop增删改查代码模板
    使用Layer Confirm弹窗没有点击确定按钮就执行了确定方法
    页面表单传值
    2018年5月2日 问题记录
    循环分页请求
    git删除commit方法和误删commit后的恢复方法
    git切换分支
    系统化的思考模式
    实践!实现纯前端下的音频剪辑处理
  • 原文地址:https://www.cnblogs.com/Urchin-C/p/11237260.html
Copyright © 2011-2022 走看看