zoukankan      html  css  js  c++  java
  • 19-字符串匹配(kmp || substr,find)

    链接:https://www.nowcoder.com/acm/contest/77/C
    来源:牛客网

    时间限制:C/C++ 2秒,其他语言4秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

    有一个字符串 让你找到这个字符串 S 里面的子串T 这个子串 T 必须满足即使这个串的前缀 也是这个
    串的后缀 并且 在字符串中也出现过一次的(提示 要求满足前后缀的同时也要在字符串中出现一次 只是前后缀可不行 输出最长满足要求字符串)

    输入描述:

    给出一个字符串 长度 1 到 1e6  全部是小写字母

    输出描述:

    如果找的到就输出这个子串T 如果不行就输出 Just a legend
    示例1

    输入

    fixprefixsuffix

    输出

    fix
    示例2

    输入

    abcdabc

    输出

    Just a legend
    方法一:kmp:注意枚举的模式串,以及原串与给定字符之间的差别:
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    string str, mo;
    int Next[1000005];
    
    void getNext(){
    	Next[0] = -1;  //一定要初始化 
    	int i = 0, j = -1, len = mo.length();
    	while(i < len){
    		if(j == -1 || mo[i] == mo[j])  //j表示前i-1个字符中前缀和后缀相等的长度 
    			Next[++i] = ++j;		   //如果跳转的值相同,则Next的下一位对应的为前一位加一	
    		else 
    			j = Next[j];   //j回溯 
    	}
    }
    
    int kmp(){
    	int ans = 0;
    	int i = 0, j = 0, l1 = str.length(), l2 = mo.length();
    	while(i < l1){
    		if(j == -1 || str[i] == mo[j]) 
    			i++, j++;
    		else
    			j = Next[j];    //只需回溯j 
    		if(j == l2)			//在原串中找到一个模式串 
    			ans++;
    	}
    	return ans;
    }
     
    int main(){
    	ios::sync_with_stdio(false);  //取消cin 与 scanf()同步,刚刚没加超时了 
    	string tt;
    	cin >> tt;
    	int len = tt.length(), flag = 1;
    	for(int i = len - 2, j; i >= 1; i--){  //枚举所以可能的前缀长度,注意不是范围不是0~len/2,要保证中间子串不用前缀后缀重合即可 
    		string s;
    		for(j = 0; j < i; j++){     //判断是否与后缀相等 
    			if(tt[j] != tt[len - i + j]){
    				break;
    			}
    			s += tt[j];
    		}
    		if(j == i){
    			mo = s;			//将前缀作为模式串 
    			getNext();
    		//	str = tt;
    			for(int k = 1; k < len - 1; k++) //中间不与前缀后缀重合的子串作为原串,注意范围!!! 
    				str += tt[k];
    			int ct = kmp();
    			if(ct >= 1){          	 //在原串中找到即可 
    				cout << s << endl;
    				flag = 0;
    				break;
    			}
    			str.clear();
    		}
    	}
    	if(flag){
    		cout << "Just a legend" << endl;
    	}
    	return 0;
    }
    /*
    aaaaa
    结果:
    aaa 
    */

      

      第二次写:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    int Next[1000005];
    
    void getNext(string p){
      int j = 0, k = -1, len = p.length();
      Next[0] = -1;
      while(j < len){
        if(k == -1 || p[j] == p[k]){
        /*
    		Next[++j] = ++k; //换成下面的if和else 
    	
    	*/	
          if(p[++j] == p[++k]){
            Next[j] = Next[k];
          }
          else{
            Next[j] = k;
          }
        }
        else{
          k = Next[k];
        }
      }
    }
    
    int main()
    {
      string str, p, pp;
      cin >> str;
      int len = str.length();
      int ct = 0, k = 1;
    
      while(k < len - 1){
        p = str.substr(0, k);
        pp = str.substr(len - k, k);
        if(p != pp){
          k++;
          continue;
        }
        getNext(p);
        int count = 0, i = 0, j = 0;
        while(i < len){
          if(j == -1 || str[i] == p[j]){
       		j++, i++;
          }
          else{
            j = Next[j];
          }
          if(j == k){
            count++;
            j = 0; i = i - k + 1; 
            if(count >= 3){
              ct = k;
              break;
            }
          }
        }
        k++;
      }
      if(ct == 0){
        cout << "Just a legend" << endl;
      }
      else{
        cout << str.substr(0, ct) << endl;
      }
        return 0;
    }
    

      

    方法二:用substr,find:

      

    #include<iostream>
    #include<cstring>
    #include <string>
    using namespace std;
    string s;
    
    int main(){
        cin >> s;
        int k = 1, l = s.size();
        string ans = "";
        while (l>2 && k<l){
            string ss = s.substr(0, k);//拷贝s第0个数开始,长度为k
            if (s.substr(l - k, k) == ss)
            {
                string sss = s.substr(1, l - 2);
                ///cout << sss.find(ss) << endl;
                if (sss.find(ss)<l - 2)
                    ans = ss;
            }
            k++;
        }
        if (ans == "")
            cout << "Just a legend" << endl;
        else
            cout << ans << endl;
    }
    

      




  • 相关阅读:
    es6 可迭代对象
    前端模板
    快速排序
    parseHTML2Vnode
    最大并发请求
    选择排序
    window命令
    Asp.net问题集锦
    ExtJs5.1.1使用中问题集锦
    Sql Server问题集锦
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/8471244.html
Copyright © 2011-2022 走看看