根据条件从java中的字符串数组中提取单词

时间:2016-02-03 19:44:35

标签: java arrays string extract prefix

我正在尝试使用Arrays和Strings进行分配。代码几乎完成,但我遇到了麻烦。每次代码运行时,它都会替换输出数组索引中的值,而不是将新值放在不同的索引中。例如,如果我试图在字符串数组中搜索包含前缀“b”的单词,则预期输出为“bat”和“brewers”,而输出则表示为“brewers”和“brewers” 。有什么建议? (ps。静态main方法用于测试目的。)

-

public static void main(String[] args) {

    String[] words = {"aardvark", "bat", "brewers", "cadmium", "wolf", "dastardly", "enigmatic", "frenetic",
            "sycophant", "rattle", "zinc", "alloy", "tunnel", "nitrate", "sample", "yellow", "mauve", "abbey",
            "thinker", "junk"};
    String prefix = "b";
    String[] output = new String[wordsStartingWith(words, prefix).length];
    output = wordsStartingWith(words, prefix);

    for (int i = 0; i < output.length; i++) {
        System.out.println("Words: " + i + " " + output[i]);
    }

}

public static String[] wordsStartingWith(String[] words, String prefix) {
    // method that finds and returns all strings that start with the prefix

    String[] returnWords;
    int countWords = 0;

    for (int i = 0; i < words.length; i++) {
        // loop to count the number of words that actually have the prefix
        if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
            countWords++;
        }
    }

    // assign length of array based on number of words containing prefix
    returnWords = new String[countWords];

    for (int i = 0; i < words.length; i++) {
        // loop to put strings containing prefix into new array
        for (int j = 0; j < returnWords.length; j++) {
            if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
                returnWords[j] = words[i];
            }
        }
    }

    return returnWords;
}

-

谢谢

灵魂

4 个答案:

答案 0 :(得分:0)

这是因为您编写的代码。如果你能够正确地思考它,你就会意识到自己的错误。

罪魁祸首

for (int j = 0; j < returnWords.length; j++) {
    if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
        returnWords[j] = words[i];
    }
}

当你得到一个匹配的单词时,你将整个输出数组设置为该单词。这意味着找到满足条件的最后一个单词将替换数组中的所有先前单词。

数组returnWords的所有元素首先被初始化为“bat”,然后每个元素被“brewers”替换

更正的代码将是这样的

int j = 0;
for (int i = 0; i < words.length; i++) {
    if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
        returnWords[j] = words[i];
        j++;
    }
}

此外,您正在进行多次迭代,而这并非完全需要。

例如这句话

String[] output = new String[wordsStartingWith(words, prefix).length];
output = wordsStartingWith(words, prefix);

可以纠正为更简单的陈述     String [] output = wordsStartingWith(words,prefix);

答案 1 :(得分:0)

您执行此操作的方式是多次循环遍历同一阵列。 您只需要检查一次值:

public static void main(String[] args) {
    String[] words = {"aardvark", "bat", "brewers", "cadmium", "wolf", "dastardly", "enigmatic", "frenetic",
            "sycophant", "rattle", "zinc", "alloy", "tunnel", "nitrate", "sample", "yellow", "mauve", "abbey",
            "thinker", "junk"};
    String prefix = "b";

    for (int i = 0; i < words.length; i++) {
        if (words[i].toLowerCase().startsWith(prefix.toLowerCase())) {
            System.out.println("Words: " + i + " " + words[i]);
        }
    }
}

答案 2 :(得分:0)

不要做两个单独的循环,而是尝试只有一个:

String[] returnWords;
int[] foundWords = new int[words.length];
int countWords = 0;

for (int i = 0; i < words.length; i++) {
    // loop to count the number of words that actually have the prefix
    if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
        foundWords[index] = words[i];
        countWords++;
    }
}

// assign length of array based on number of words containing prefix
returnWords = new String[countWords];
for (int i = 0; i < countWords; i++) {
    returnWords[i] = foundWords[i];
}

我的方法有另一个数组(foundWords),用于在第一个循环中找到的所有单词,其大小为words,以防每个单词以前缀开头。 index会跟踪foundWords中找到的字词的放置位置。最后,您只需浏览countWords并将每个元素分配给returnWords

这不仅可以修复你的代码,而且会对其进行优化,使其运行得更快(非常轻微;单词库越大,搜索速度越快)。

答案 3 :(得分:0)

不要重新发明轮子。您的代码可以被这个单一,易于阅读,无错误的行代替:

String[] output = Arrays.stream(words)
    .filter(w -> w.startsWith(prefix))
    .toArray(String[]::new);

或者,如果您只想打印匹配的单词:

Arrays.stream(words)
    .filter(w -> w.startsWith(prefix))
    .forEach(System.out::println);