在不同的String中搜索一个String

时间:2018-02-25 17:14:57

标签: java arrays string performance linked-list

当我尝试比较两个字符串时,我遇到了一些麻烦。 我的第一个字符串是一个单词,我的第二个字符串是形成我的单词的一些字母,例如:

String 1, my word: "test"
String 2, my soup: "adhesljdtth"

在这种情况下,我得到了两个字符串的所有字符,并开始处理它们,当我在汤中找到一些属于我的字的字符时,我需要将其从汤中取出,然后转到下一个元件。

我找到了一些比较它并使用得到结果的方法:StringBuilder,LinkedList,数组等等,所有这些都使用小字符串,但是当我得到一个包含数百万个字符的字符串时,我遇到了一些性能问题。在这种情况下,我尝试使用二进制搜索,但即使这样做也需要很长时间来处理我的结果。

我正在使用Array.sort函数对我的两个字符串进行排序。

为了验证汤是否有所有字母形成我的话,我这样做:

for (int i = 0; i < wordLenght; i++) {
    char key = wordCharList[i];
    int length = soupCharList.size();
    int low = 0;
    int high = length - 1;

    while (low <= high) {

        int mid = (low + high) >>> 1;
        char midVal = soupCharList.get(mid);

        if (midVal < key) {
            low = mid + 1;
        }
        else if (midVal > key) {
            high = mid - 1;
        }
        else if(midVal == key) {
            soupCharList.remove(mid);
            break;
        }
        if(high == -1) {   
            return false;
        }
    }
}
    return true;
}

您是否有任何想法如何将其与更好的表现进行比较?

1 个答案:

答案 0 :(得分:0)

  

我尝试比较两个字符串

要比较字符串,请使用String#compare。显然,你正在做其他事情,所以要正确命名。

  

我找到了一些方法来比较它并使用以下结果获取结果:StringBuilder,LinkedList,数组等等,都使用小字符串,但是当我得到一个包含数百万个字符的字符串时

这些数据结构都没有快速查找。请使用SetMap

  • 如果您想知道,如果汤中包含该单词中的所有字符,请使用Set#containsAll
  • 如果您想知道,如果汤中包含单词中出现次数的所有字符,请使用Map<Character, Integer>
  • 为了计算,Guava Multiset<Character>更容易使用。

由于字符数限制为较小的值,您可以使用包含计数的数组。这不是很一般,但它非常简单且非常快:

int[] wordCounts = makeCounts(word);
int[] soupCounts = makeCounts(soup);
for (int i=0; i<wordCounts.length; ++i) {
    if (wordCounts[i] > soupCount[i]) return false;
}
return true;

int[] makeCounts(String s) {
    int[] result = new int[Character.MAX_VALUE + 1];
    for (int i=0; i<s.length(); ++i) ++result[s.charAt(i)];
    return result;
}

由于您的字符串不使用所有字符,因此可以进行优化。