您的位置:首页 > 编程语言 > Java开发

算法笔记_106:蓝桥杯练习 算法提高 周期字串(Java)

2017-03-21 13:45 591 查看

1 问题描述

问题描述
  右右喜欢听故事,但是右右的妈妈总是讲一些“从前有座山,山里有座庙,庙里有个老和尚给小和尚讲故事,讲的什么呢?从前有座山……”这样循环的故事来搪塞右右。
  我们定义,如果一个字符串是以一个或者一个以上的长度为k的重复字符串所连接成的,那么这个字符串就叫做周期为k的串。
  例如:
  字符串’abcabcabcabc’周期为3,因为它是由4个循环’abc’组成的。它同样是以6为周期(两个重复的’abcabc’)和以12为周期(一个循环’abcabcabcabc’)。
  右右现在想给他的朋友大灰狼转述妈妈讲的故事,请帮他写一个程序,可以测定一个字符串的最小周期。
输入格式
  一个最大长度为100的无空格的字符串。
输出格式
  一个整数,表示输入的字符串的最小周期。
样例输入
HaHaHa
样例输出
2
样例输入
Return0
样例输出
7

2 解决方案

2.1 第一印象解法(80分)

初步看到此题,第一印象就是字符串模式匹配,那么遇到此问题,最佳的时间效率当然是使用KMP字符串模式匹配算法啦,结果运行测评分数为80分,原因:运行超时。



以下代码仅供参考哦。

具体代码如下:

import java.util.Scanner;

public class Main {

public int[] getNext(char[] arrayB) {
int[] next = new int[arrayB.length + 1];
int j = 0;
for(int i = 0;i < arrayB.length;i++) {
while(j > 0 && arrayB[i] != arrayB[j])
j = next[j];
if(arrayB[j] == arrayB[i])
j++;
next[i + 1] = j;
}
return next;
}

public int getKMP(char[] arrayA, char[] arrayB) {
int max = 0;   //统计arrayB在arrayA中匹配子串的总个数
int[] next = getNext(arrayB);
int j = 0;
int tempi = -1;  //记录每一次匹配完成时i的值
for(int i = 0;i < arrayA.length;i++) {
while(j > 0 && arrayA[i] != arrayB[j])
j = next[j];
if(arrayA[i] == arrayB[j])
j++;
if(j == arrayB.length) {
if(i - tempi != arrayB.length)   //针对题意运行时间要求,做出此处判定
break;
tempi = i;   //更新tempi值
max++;
j = 0;
}
}
return max;
}

public void printResult(String A) {
char[] arrayA = A.toCharArray();
int max = arrayA.length;
for(int i = 0;i < arrayA.length;i++) {
int len = i + 1;
if(len > arrayA.length / 2)
break;
else if(arrayA.length % len != 0)
continue;
char[] arrayB = new char[len];
for(int j = 0;j < arrayB.length;j++)
arrayB[j] = arrayA[j];
int tempMax = arrayA.length / arrayB.length;
if(tempMax == getKMP(arrayA, arrayB)) {  //当匹配字符串arrayB刚好组成arrayA时
max = arrayB.length;
break;
}
}
System.out.println(max);
return;
}

public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
String A = in.next();
test.printResult(A);
}
}


2.2 借鉴网友解法(100分)

具体思想如下(引用文末参考资料1中讲解):





具体代码如下:

import java.util.Scanner;

public class Main {

public void printResult1(String A) {
char[] arrayA = A.toCharArray();
int max = arrayA.length;
for(int i = 0;i < arrayA.length;i++) {
int k = i + 1;
if(k > arrayA.length / 2)
break;
else if(arrayA.length % k != 0)
continue;
int j = k;
for(;j < arrayA.length;j++) {
if(arrayA[j] != arrayA[j % k])
break;
}
if(j == arrayA.length) {
max = k;
break;
}
}
System.out.println(max);
return;
}

public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
String A = in.next();
test.printResult1(A);
}
}


[b]参考资料:[/b]

1.【算法-字符串】【周期串】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: