求一个字符中连续出现次数最多的子串

直接按我的思路先看一个例子
条件1 字符串A"323213213231312321323213213213213213123213213213232"
求:该串中连续次数最多的子串B
关键字:连续 次数最多
1. 遍历字符串,把相同字符的"位置"存入List中,并将char : List<Integer>置于Map中 
那么上述例子则有: 
字符3:[0, 2, 5, 8, 10, 12, 15, 18, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 49] 
字符2 : [1, 3, 6, 9, 14, 16, 19, 21, 24, 27, 30, 33, 37, 39, 42, 45, 48, 50] 
字符1:[4, 7, 11, 13, 17, 22, 25, 28, 31, 34, 36, 40, 43, 46]

2. 分析上述的一个字符位置列表,按下死步骤找到其中的子列表,这样的子列表应该满足: 
2.1 该子列表里面的值递增 
2.2 对应的下标也要递增 
2.3 列表中值其实为字符A之间的位置,相邻的两个位置其后的字符应该也一样,否则应该剔除掉不同的

3. 存储查找的结果

假如字符串A中存在连续的字符串B
设连续字符串的单元字符串为b(b不可能是连续的字符串)
设b的首字符 b0在b中的位置为b1b2b3b4...
首先有:b1,b2,b3...递增,无需累述
接着:b1, b2, b3...下标递增。如果有与b0相同的字符存在于b中,那么存在于b0与b1之间的个数应该与b1与b2之间存在的个数一样
最后:判断b1b2之间与b2b3之间的元素是否相同
代码如下:
import  java.util.ArrayList;
import  java.util.HashMap;
import  java.util.Iterator;
import  java.util.List;
import  java.util.Map;
import  java.util.Map.Entry;

/**

 * 
 * 
@author Daniel
 * 
@since 2008-5-4
 
*/

public   class  TestSub  {
    
private static final String LETTER_CONSTANT = "123";

    
private static final int LETTERS_LENGTH = LETTER_CONSTANT.length();

    
private static final int MAX_LENGTH = 300;

    
private static Map<Character, List<Integer>> charsMap = new HashMap<Character, List<Integer>>();

    
private static String string;

    
private static List<Store> stores = new ArrayList<Store>(0);

    
private static int max = 1;

    
public static void main(String[] args) {
        find();
    }

    
    
public static void find(){
        string 
= randomString();
        
//string = "323213213231312321323213213213213213123213213213232";
        System.out.println(string);
        countChar();
        Iterator
<Entry<Character, List<Integer>>> it = charsMap.entrySet()
                .iterator();
        
for (; it.hasNext();) {
            List
<Integer> value = it.next().getValue();
            
//System.out.println(value);
            findIncrease(value);
        }


        System.out.println(
"============= start length count");
        
for (Store store : stores) {
            System.out.println(store.start 
+ " " + store.offset + " "
                    
+ store.count);
            System.out.println(string.substring(store.start, store.start
                    
+ store.offset * store.count));
        }

    }


    
public static String randomString() {
        
int index = 0;
        
//int length = (int) (Math.random() * MAX_LENGTH);
        int length = MAX_LENGTH;
        
char[] randomString = new char[length];
        
for (int i = 0; i < length; i++{
            index 
= (int) (Math.random() * LETTERS_LENGTH);
            randomString[i] 
= LETTER_CONSTANT.charAt(index);
        }

        
return new String(randomString);
    }


    
public static void countChar() {
        
for (int i = 0; i < string.length(); i++{
            
char c = string.charAt(i);
            List
<Integer> indexes = charsMap.get(c);
            
if (indexes == null{
                indexes 
= new ArrayList<Integer>();
                charsMap.put(c, indexes);
            }

            indexes.add(i);
        }

    }


    
/**
     * 
     * 
@param list
     
*/

    
public static void findIncrease(List<Integer> list) {
        
// int max = 1;
        
// [3, 5, 6, 8, 11, 14, 17, 18, 20, 21],假如一共出现了10个该字符
        for (int i = 0; i < list.size(); i++{
            
// 比如外层标志为第0个,这里代表的数字是3
            
// 那么内层循环的从第i个,直到第(10-1 + i)/2 = 4(即内层循环小于等于4);
            for (int j = i + 1; j <= (list.size() - 1 + i) / 2; j++{
                
// 两者在字符串中的位置差
                int offsetInString = list.get(j) - list.get(i);
                
// 两者在列表中的位置差
                int offset = j - i;
                
// 本身算一次
                int count = 1;
                
boolean same = true;
                
while (same && i + offset * count < list.size()) {
                    
if (list.get(i + offset * count) == list.get(i) + count
                            
* offsetInString) {
                        count
++;
                    }
 else {
                        same 
= false;
                    }

                }

                
// 如果只有一次,则继续
                if (count == 1{
                    
continue;
                }


                
int result = check(list.get(i), offsetInString, count);
                
if (result > max) {
                    stores.clear();
                    stores.add(
new Store(list.get(i), offsetInString, result));
                    max 
= result;
                }
 else if (result == max) {
                    stores.add(
new Store(list.get(i), offsetInString, result));
                }

            }

        }

    }


    
public static int check(int start, int offset, int count) {
        
for (int i = 0; i < count; i++{
            
for (int j = 0; j < offset; j++{
                
if (start + j + offset * i >= string.length()
                        
|| string.charAt(start + j) != string.charAt(start + j
                                
+ offset * i)) {
                    count 
= i;
                    
break;
                }

            }

        }

        
return count;
    }

}


class  Store  {
    
int start;

    
int offset;

    
int count;

    
public Store(int start, int offset, int count) {
        
this.start = start;
        
this.offset = offset;
        
this.count = count;
    }

}


说的真乱,代码也没注释好,有空再改吧
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值