要找到一个字符串的排列,可以使用数论。
但是在使用此算法回答问题之前,您必须事先了解该算法背后的“理论”。
有一种方法可以使用质数计算字符串的哈希值。
相同字符串的每个排列都将给出相同的哈希值。所有其他不是排列的字符串组合将给出另一些哈希值。
哈希值由c
1 * p
1 + c
2 * p
2 + ... + c
n * p
n计算
其中c
i是字符串中当前字符的唯一值,p
i是c
i字符的唯一质数值。
以下是实现内容。
public class Main {
static int[] primes = new int[] { 2, 3, 5, 7, 11, 13, 17,
19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103 };
public static void main(String[] args) {
final char[] text = "abcxaaabbbccyaxbcayaaaxycab"
.toCharArray();
char[] abc = new char[]{'a','b','c'};
int match = val(abc);
for (int i = 0; i < text.length - 2; i++) {
char[] _123 = new char[]{text[i],text[i+1],text[i+2]};
if(val(_123)==match){
System.out.println(new String(_123) );
}
}
}
static int p(char c) {
return primes[(int)c - (int)'a'];
}
static int val(char[] cs) {
return
p(cs[0])*(int)cs[0] + p(cs[1])*(int)cs[1] + p(cs[2])*(int)cs[2];
}
}
这段代码的输出结果为:
abc
bca
cab
i=3
(子字符串xya
)处匹配,则映射将为[a->1, x->1, y->1]
。在草堆中前进时,减少haystack[i]
的字符计数,并增加haystack[i+needle.length()]
的计数。(删除零以确保Map.equals()
有效,或者只是实现自定义比较。) - millimoosematchedCharactersCnt
的变量会怎样呢?在haystack字符串的开头,将其设为0。每次你将映射“向着”目标值进行更改时 - 增加该变量的值。每次你将映射“远离”目标值进行更改时 - 减少该变量的值。每次迭代时,检查变量是否等于needle字符串的长度。如果是,则找到了匹配项。这比每次完全比较映射要快。 - bezmax