从算法上看,这可能不是最有效的解决方案,但是从类设计的角度来看,这是干净的。该解决方案采用比较“排序的”给定单词的方法。
如果一个单词包含相同数字的相同字母,我们可以说它是另一个单词的排列。这意味着您可以将单词从a转换
String为a
Map<Character,Integer>。此类转换将具有复杂度O(n),其中n是的长度
String,假设实现中的插入
Map成本为O(1)。
Map将包含单词中找到的所有字符作为键,并包含字符频率的值。
实例 。 abbc转换为[a->1, b->2, c->1]
bacb转换为[a->1, b->2, c->1]
因此,如果您必须知道两个单词是否是另一个单词的置换,可以将它们都转换为maps,然后调用
Map.equals。
然后,您必须遍历文本字符串,并将转换应用于要查找的单词长度相同的所有子字符串。
Inerdial提出的改进
通过以“滚动”方式更新地图可以改进此方法。
也就是说,如果您要
i=3在OP中的示例干草堆中的索引处(子字符串
xya)进行匹配,则地图将为
[a->1, x->1,y->1]。在大海捞针中前进时,请减少的字符计数
haystack[i],然后增加的计数
haystack[i+needle.length()]。
(删除零以确保
Map.equals()有效,或仅实施自定义比较。)
Max提出的改进
如果我们还引入
matchedCharactersCnt变量怎么办?在大海捞针的开始
0。每次将地图更改为所需值时,都会增加变量。每次将其更改为偏离所需值时,都会减小变量。每次迭代都检查变量是否等于针的长度。如果是-
您找到了匹配项。这比每次比较完整地图要快。
Max提供的伪代码:
needle = "abbc"text = "abbcbbabbcaabbca"needleSize = needle.length()//Map of needle character countstargetMap = [a->1, b->2, c->1]matchedLength = 0curMap = [a->0, b->0, c->0]//Initial map initializationfor (int i=0;i<needle.length();i++) { if (curMap.contains(haystack[i])) { matchedLength++ curMap[haystack[i]]++ }}if (matchedLength == needleSize) { System.out.println("Match found at: 0");}//Search itselffor (int i=0;i<haystack.length()-needle.length();i++) { int targetValue1 = targetMap[haystack[i]]; //Reading from hashmap, O(1) int curValue1 = curMap[haystack[i]]; //Another read //If we are removing beneficial character if (targetValue1 > 0 && curValue1 > 0 && curValue1 <= targetValue1) { matchedLength--; } curMap[haystack[i]] = curValue1 + 1; //Write to hashmap, O(1) int targetValue2 = targetMap[haystack[i+needle.length()]] //Read int curValue2 = curMap[haystack[i+needle.length()]] //Read //We are adding a beneficial character if (targetValue2 > 0 && curValue2 < targetValue2) { //If we don't need this letter at all, the amount of matched letters decreases matchedLength++; } curMap[haystack[i+needle.length()]] = curValue2 + 1; //Write if (matchedLength == needleSize) { System.out.println("Match found at: "+(i+1)); }}//Basically with 4 reads and 2 writes which are //independent of the size of the needle,//we get to the maximal possible performance: O(n)


