简体   繁体   English

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

[英]Extract words from an array of Strings in java based on conditions

I am trying to do an assignment that works with Arrays and Strings. 我正在尝试做一个与数组和字符串一起使用的赋值。 The code is almost complete, but I've run into a hitch. 代码几乎完成了,但是我遇到了麻烦。 Every time the code runs, it replaces the value in the index of the output array instead of putting the new value in a different index. 每次代码运行时,它都会替换输出数组的索引中的值,而不是将新值放入另一个索引中。 For example, if I was trying to search for the words containing a prefix "b" in the array of strings, the intended output is "bat" and "brewers" but instead, the output comes out as "brewers" and "brewers". 例如,如果我尝试在字符串数组中搜索包含前缀“ b”的单词,则预期的输出为“ bat”和“ brewers”,但是输出的结果为“ brewers”和“ brewers” 。 Any suggestions? 有什么建议么? (ps. The static main method is there for testing purposes.) (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;
}

-- -

Thank You 谢谢

Soul 灵魂

Its because of the code you have written. 这是因为您编写的代码。 If you would have thought it properly you would have realized your mistake. 如果您认为正确的话,您将意识到自己的错误。

The culprit code 罪魁祸首

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

When you get a matching word you set whole of your output array to that word. 当您获得匹配的单词时,请将整个输出数组设置为该单词。 This would mean the last word found as satisfying the condition will replace all the previous words in the array. 这意味着找到的满足条件的最后一个单词将替换数组中所有先前的单词。

All elements of array returnWords gets first initialized to "bat" and then each element gets replaced by "brewers" 首先将数组returnWords的所有元素初始化为“ bat”,然后将每个元素替换为“ brewers”

corrected code will be like this 更正的代码将是这样

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++;
    }
}

Also you are doing multiple iterations which is not exactly needed. 另外,您正在执行多次迭代,这并不是完全需要的。

For example this statement 例如此语句

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

can be rectified to a simpler statement String[] output = wordsStartingWith(words, prefix); 可以更简单地声明为String [] output = wordsStartingWith(words,prefix);

The way you're doing this is looping through the same array multiple times. 您执行此操作的方法是多次遍历同一数组。 You only need to check the values once: 您只需要检查一次值:

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]);
        }
    }
}

Instead of doing two separate loops, try just having one: 而不是执行两个单独的循环,请尝试仅执行一个循环:

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];
}

My method has another array ( foundWords ) for all the words that you found during the first loop which has the size of words in case every single word starts with the prefix. 我的方法为您在第一个循环中找到的所有单词提供了另一个数组( foundWords ),该数组具有words的大小,以防每个单词都以前缀开头。 And index keeps track of where to place the found word in foundWords . index跟踪找到的单词在foundWords放置位置。 And lastly, you just have to go through the countWords and assign each element to your returnWords . 最后,您只需要遍历countWords并将每个元素分配给您的returnWords

Not only will this fix your code but it will optimize it so that it will run faster (very slightly; the bigger the word bank is, the greater fast it will search through). 这不仅会修复您的代码,还将对其进行优化,以便使其运行更快(非常轻微;单词库越大,搜索到的速度越快)。

Don't reinvent the wheel. 不要重新发明轮子。 Your code can be replaced by this single, easy to read, bug free, line: 您的代码可以替换为以下易于理解的单一代码行:

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

Or if you just want to print the matching words: 或者,如果您只想打印匹配的单词:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM