直接按我的思路先看一个例子
条件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之间的元素是否相同
代码如下:
说的真乱,代码也没注释好,有空再改吧
条件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;
}
}
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;
}
}
说的真乱,代码也没注释好,有空再改吧