给定一个字符串 s , 请计算输出含有连续两个 s 作为子串的最短字符串。 注意两个 s 可能有重叠部分。例如, "ababa" 含有两个 "aba".
数据范围:输入的字符串长度满足 ,且保证只含有小写英文字母
输入包括一个字符串s,字符串长度length(1 ≤ length ≤ 50),s中每个字符都是小写字母.
输出一个字符串,即含有连续两个s作为子串的最短字符串。
abracadabra
abracadabracadabra
a
aa
import java.util.Scanner; public class Main{ public static void main (String[] args) { Scanner input = new Scanner(System.in); String s = input.nextLine(); String out = s + s; String sub = ""; int len = s.length(); int index = len; for(int i= len-1; i >= 1; i--) { sub = s.substring(i,len); if(s.startsWith(sub)) index = i; } if(index != len) out = s + s.substring(len-index,len); System.out.print(out); } }//逆序取子串,用s.startswith(s1)判断子串是不是符合条件,记录最大的子串的index,
out = s + s.substring(len-index,len);//输出有子串时的结果
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = br.readLine().trim(); String newS = ""; int start; for(start = 1; start < s.length(); start++){ if(s.substring(start, s.length()).equals(s.substring(0, s.length() - start))){ newS = s.substring(0, start) + s; break; } } if(start == s.length()) System.out.println(s + s); else System.out.println(newS); } }
package main import "fmt" func main() { var s string fmt.Scan(&s) length := len(s) if length == 1 { fmt.Println(s+s) } maxSameLenth := 0 //比较字符串前i-1个字符和最后i-1个字符是否相同 for i:=1; i<length; i++ { if s[:i]==s[length-i:] { maxSameLenth = i } } newString:=s+s[maxSameLenth:] fmt.Println(newString) }Golang实现
#include <stdio.h> #include <string.h> char s[60]; int main() { int i,j,k,flag,len; gets(s); len = strlen(s); for(i=1;i<len;i++) { flag = 1; for(j=i,k=0;j<len;j++,k++) if(s[j]!=s[k]) { flag = 0; break; } if(flag) { for(j=0;j<i;j++) putchar(s[j]); puts(s); return 0; } } for(j=0;j<len;j++) putchar(s[j]); puts(s); return 0; }
import java.util.*; public class Main { private static final int MAX = 50005; public static void main(String[] args) { Scanner sc = new Scanner(System.in); char[] in = sc.next().toCharArray(); int n = in.length; StringBuilder sb = new StringBuilder(); for (int i=1; i<n; i++) { boolean flag = true; for (int j=0; i+j<n; j++) { if (in[i+j] != in[j]) { flag = false; break; } } if (flag) { sb.append(in, 0, i); sb.append(in); System.out.println(sb.toString()); return; } } sb.append(in); sb.append(in); System.out.println(sb.toString()); } }
思路:题意为判断从字符串最后一位开始算,存在多少位与从头开始的相应位数相等 #include <iostream> #include <string> using namespace std; int main() { string s; cin>>s; int l=s.length(); //字符串长度 if(l==0) return 0; if(l==1) { cout<<s+s<<endl; return 0; } int j=1; //截取字符个数 int count=0; string temp; //保存截取的字符 for(int i=l-1;i>0;i--) { string s1=s.substr(i,j); //从后往前 string s2=s.substr(0,j); //从前往后 j++; if(s1==s2) { temp=s2; count++; } else { if(j==1) // { break; } } } if(count==0) //表示重复的个数为零 { cout<<s+s<<endl; } else { string re=s.substr(temp.length(),l-temp.length()); //截取不重复的部分 cout<<s+re<<endl; } return 0; }
#include<iostream> #include<stdio.h> #include<algorithm> #include<cstring> using namespace std; int main(){ string s; cin >> s; //求next+1数组 int* next = new int[s.size() + 1]; int k = -1; int j = 0; next[0] = -1; while(j < s.size()){ if(k == -1 || s[k] == s[j]) { j++; k++; next[j] = k; } else{ k = next[k]; } } //看next+1数组最后一位的值 表示前缀后缀相同字母的个数 cout << s + s.substr(next[s.size()]) << endl; delete[] next; }
import sys # Rolling hash s = sys.stdin.readline().strip('\n') l = len(s) - 2 r = 1 base = 26 coef = lambda x: ord(x) - ord('a') + 1 head = 0 for i in range(0, len(s) - 1): head = head * base + coef(s[i]) tail = 0 for i in range(1, len(s)): tail = tail * base +coef(s[i]) most_significant = base ** (len(s) - 2) while head != tail: head = (head - coef(s[l])) // base tail = tail - (coef(s[r]) * most_significant) most_significant //= base l -= 1 r += 1 print(s + s[l+1:])