zoukankan      html  css  js  c++  java
  • Power Strings(kmp妙解)

    Power Strings

    Time Limit : 6000/3000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
    Total Submission(s) : 29   Accepted Submission(s) : 14
    Problem Description
    Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).
     
    Input
    Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
     
    Output
    For each s you should print the largest n such that s = a^n for some string a.
     
    Sample Input
    abcd aaaa ababab .
     
    Sample Output
    1 4 3
     
    题解:让找串的重复度;

    描述:

    对于数组s[0~n-1],计算next[0~n](多计算一位)。

    考虑next[n],假设t=n-next[n],如果n%t==0,则t就是问题的解,否则解为1。

    这样考虑:

    比如字符串"abababab",

                a  b a b a b a b *

    next     -1 0 1 2 3 4 5 6  7

    考虑这样的模式匹配,将"abababab#"当做主串,"abababab*"当做模式串,于是进行匹配到n(n=8)时,出现了不匹配:

     主串      abababab#

     模式串   abababab*

    于是模式串需要回溯到next[*]=7,这之前的主串和模式串对应相等,于是需要模式串向右滚动的位移是d=n-next[n]=2,即:

                123456789 

    主串      abababab#

    模式串       abababab*

    于是可以看出,s[0~1]=s[3~4]=s[5~6]=s[7~8]。

    所以位移d=n-next[n]可以看作是构成字符串s的字串(如果n%d==0,存在这样的构成),相应的重复次数也就是n/d。

    n-next[n]也就是当前最小匹配的字串长度。。。。。此处的next数组相当于代码中的p数组......

     代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 const int MAXN=1000010;
     4 int p[MAXN];
     5 char s[MAXN];
     6 int n,len;
     7 void getp(){
     8     int i=0,j=-1;
     9     p[0]=-1;
    10     while(i<len){
    11         if(j==-1||s[j]==s[i]){
    12             i++;j++;
    13             p[i]=j;
    14         }
    15         else j=p[j];
    16     }
    17 }
    18 int main(){int answer;
    19     while(scanf("%s",s),strcmp(s,".")){
    20         memset(p,0,sizeof(p));
    21         len=strlen(s);
    22         getp();
    23         /*for(int i=0;i<=len;i++)printf("%d ",p[i]);
    24         puts("");*/
    25         answer=1;
    26         if(len%(len-p[len])==0)answer=len/(len-p[len]);
    27         printf("%d
    ",answer);
    28     }
    29     return 0;
    30 }
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace  std;
    typedef long long LL;
    #define mem(x,y) memset(x,y,sizeof(x))
    #define SI(x) scanf("%d",&x)
    #define PI(x) printf("%d",x)
    const int INF=0x3f3f3f3f;
    const int MAXN=1000010;
    int p[MAXN];
    
    void getp(char* s){
    	int len=strlen(s);
    	int i=0,j=-1;
    	p[0]=-1;
    	while(i<len){
    		if(j==-1||s[i]==s[j]){
    			i++;j++;
    			p[i]=j;
    		}
    		else j=p[j];
    	}
    }
    
    int main(){
    	char s[MAXN];
    	while(~scanf("%s",s),strcmp(s,".")){
    		getp(s);
    		int len=strlen(s);
    		if(len==0){
    			puts("0");continue;
    		}
    		if(p[len]!=-1&&len%(len-p[len])==0){
    			printf("%d
    ",len/(len-p[len]));
    		}
    		else puts("1");
    	}
    	return 0;
    }
    

      下面是修正过的:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    typedef long long LL;
    const int MAXN = 1000010;
    char s[MAXN];
    int next[MAXN];
    void getp(){
        int i = 0, j = -1;
        next[i] = j;
        while(s[i]){
            if(j == -1 || s[i] == s[j]){
                i++;j++;
                next[i] = j;
                if(s[i] == s[j])
                    next[i] = next[j];
            }
            else
                j = next[j];
        }
    }
    
    int main(){
        while(scanf("%s", s), s[0] != '.'){
            getp();
            int len = strlen(s);
          //  for(int i = 0; i <= len; i++){
          //  printf("%d ", next[i]);}puts("");
            if(len % (len - next[len]) == 0 && len / (len - next[len]) > 1){
                printf("%d
    ", len / (len - next[len]));
            }
            else puts("1");
        }
        return 0;
    }

     java写法:

    import java.util.Scanner;
    
    public class kmp{
        public static class newkmp extends kmpmod{
            public void work(char[] str){
                getp(str);
                //System.out.print(p[len]);
                if(len % (len - p[len]) == 0)
                    System.out.println(len/(len - p[len]));
                else 
                    System.out.println(1);
            }
        }
        public static char[] str = new char[1000010];
        public static void main(String[] argv){
            Scanner cin = new Scanner(System.in);
            newkmp kmp1 = new newkmp();
            while(cin.hasNext()){
                str = cin.next().toCharArray();
                if(str.length == 1 && str[0] == '.')
                    break;
                //System.out.print(str);
                kmp1.work(str);
            }
        }
    }
    abstract class kmpmod{
        protected int p[] = new int[1000010];
        protected int len;
        public void getp(char[] str){
            for(int i = 0; i < p.length; i++){
                p[i] = 0;
            }
            len = str.length;
            int i = 0, j = -1;
            p[0] = -1;
            while (i < str.length) {
                if(j == -1 || str[i] == str[j]){
                    i++; j++;
                    p[i] = j;
                }
                else{
                    j = p[j];
                }
            }
        }
        public abstract void work(char[] str);
    }
  • 相关阅读:
    案例3:歌舞娱乐放映游艺建筑防火案例分析(一)
    案例2:丙类仓库建筑防火案例分析
    第三篇 第八章泡沫灭火系统(二)
    第三篇 第七章气体灭火系统(三)
    FreeMarker 语法 null 的处理
    FreeMarker 语法 date 类型处理
    FreeMarker 语法 list
    FreeMarker 语法 访问 pojo 的属性
    mysql 去重
    FreeMarker hello
  • 原文地址:https://www.cnblogs.com/handsomecui/p/4710836.html
Copyright © 2011-2022 走看看