标签:flag sof while scanner ros imp div hdu com
题目大意:求字符串的前缀是否为周期串,若是,打印出循环节的长度以及循环次数。
这道题考察的是KMP算法中next数组的应用,必须理解透next[]数组代表的含义才t能通过它解决这道题。思路是先构造出 next[] 数组,下标为 i,定义一个变量 t = i - next[i] 就是next数组下标和下标对应值的差,如果这个差能被下标i整除,即 i%t==0 ,则说明下标i之前的字符串(周期性字符串长度为 i)一定可以由一个前缀周期性的表示出来,这个前缀的长度为刚才求得的那个差,即 t,则这个前缀出现的次数为 i/t 。所以最后输出 i 和 i/t 即可。
代码:
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.Scanner; 4 5 public class HDU1358 { 6 7 public static void main(String[] args) { 8 Scanner scanner = new Scanner(System.in); 9 List<String> list = new ArrayList<String>(); 10 11 while(true){ 12 int n = scanner.nextInt(); 13 if(n==0) break; 14 String s = scanner.next(); 15 list.add(s); 16 } 17 for(int j = 0;j<list.size();j++){ 18 String s = list.get(j); 19 20 int []next = next(s); 21 System.out.println("Test case #"+(j+1)); 22 boolean flag = false; 23 for(int i=2;i<next.length;i++){ 24 int k = next[i]; 25 int t = i-k; 26 if (i%t==0&&i/t>1) { 27 System.out.println(i +" "+i/t); 28 } 29 } 30 // if (!flag) System.out.println(0+" "+0); 31 System.out.println(); 32 } 33 } 34 35 private static int[] next(String s) { 36 if(s==null||s.length()==0)return null; 37 int[]next = new int[s.length()+1]; 38 next[0] = -1; 39 if(s.length()==1) return next; 40 next[1] = 0; 41 int j = 1; 42 int k = next[j]; 43 while(j<s.length()){ 44 if(k==-1||s.charAt(j)==s.charAt(k)){ 45 next[++j] = ++k; 46 }else { 47 k = next[k]; 48 } 49 } 50 return next; 51 } 52 53 }
结果:
标签:flag sof while scanner ros imp div hdu com
原文地址:https://www.cnblogs.com/xiaoyh/p/10325439.html