给定一个字符串 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:])