如何删除数组中的“空”元素?

时间:2019-01-08 20:58:48

标签: java arrays algorithm array-algorithms

我目前正在进行编码挑战,声明:

给出单词列表,返回只能在美国键盘的一行上使用字母输入的单词,如下图(这是QWERTY键盘的图像)。

示例:

Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]

我为解决此问题所做的工作是编写一个for循环,然后执行if将所有行(例如QWERTY)替换为""的语句,如果长度更长大于1,则不能连续输入该单词。我几乎得到了正确的输出,但是我的数组包含空元素。

我的输出是:

[null,"Alaska","Dad",null]

如何返回不包含这些空元素的数组?为了完成这一挑战,我必须返回一个String[]数组。我不能使用ArrayList来返回。

class Solution {
    public String[] findWords(String[] words) {
    String[] result = new String[words.length];

    String row1 = "qwertyuiop";
    String row2 = "asdfghjkl";
    String row3 = "zxcvbnm";

    for (int i = 0 ; i < words.length; i++) {
        if (words[i].toLowerCase().replaceAll("[" + row1 + "]", "").length() == 0 ||
           words[i].toLowerCase().replaceAll("[" + row2 + "]", "").length() == 0 ||
           words[i].toLowerCase().replaceAll("[" + row3 + "]", "").length() == 0) {
            if (words[i] != null) {
                result[i] = words[i];
            }


        }
       }

    return result;
    }


}

6 个答案:

答案 0 :(得分:5)

使用此衬纸:

Arrays.stream(result).filter(Objects::nonNull).toArray(String[]::new)

过滤数组并获取所有非null的对象。不要忘记将流转换回数组。

答案 1 :(得分:3)

您可以使用以下命令从字符串数组中删除所有空值:

List<String> list = new ArrayList<String>(Arrays.asList(myArray));
list.removeAll(Collections.singleton(null));
String[] result = list.toArray(new String[list.size()]);

答案 2 :(得分:2)

原始问题是您返回的Array与原始Array的大小相同。因此,如果任何元素都不匹配,则Array中的一个插槽将保留为默认值null。您需要跟踪需要复制多少项。您可以使用计数器和Arrays.copyOf()来完成此操作。

就Java 8+而言,我们可以做到:

public static String[] findWords(String[] words) {
    return Stream.of("asdfghjkl", "qwertyuiop", "zxcvbnm")
                 .filter(row -> Arrays.stream(words)
                           .anyMatch(e -> e.replaceAll("[" + row + "]","")                  
                           .isEmpty())
                 ).toArray(String[]::new);
}

这将使用Stream.of创建一个Stream行,并通过words数组进行过滤,仅将仅由字母组成的行保留在键盘上的单行中

答案 3 :(得分:1)

如果您确实需要返回String数组,则可以只使用ArrayList而不是数组,然后在末尾调用toArray

    public String[] findWords(String[] words) {
        List<String> result = new ArrayList<>();

        String row1 = "qwertyuiop";
        String row2 = "asdfghjkl";
        String row3 = "zxcvbnm";

        for (int i = 0; i < words.length; i++) {
            if (words[i].toLowerCase().replaceAll("[" + row1 + "]", "").length() == 0 ||
                    words[i].toLowerCase().replaceAll("[" + row2 + "]", "").length() == 0 ||
                    words[i].toLowerCase().replaceAll("[" + row3 + "]", "").length() == 0) {
                if (words[i] != null) {
                    result.add(words[i]);
                }
            }
        }

        return result.toArray(new String[0]);
    }

答案 4 :(得分:0)

您的结果数组将以单词数组的大小初始化。 您可以使用ArrayList进行动态分配。

返回ArrayList的toArray方法后,将返回所需的定序数组。

如果不允许在代码中使用ArrayList,我将寻找如何动态调整结果数组的大小。

答案 5 :(得分:0)

尝试将非空值存储在另一个变量中并对其进行计数,使用该计数初始化另一个数组,然后将值复制到后者。演示如下:

class Solution {
    public static String[] findWords(String[] words) {
    String[] resultWithNull = new String[words.length];
    int counter = 0;

    String row1 = "qwertyuiop";
    String row2 = "asdfghjkl";
    String row3 = "zxcvbnm";

    for (int i = 0 ; i < words.length; i++) {
      if (words[i].toLowerCase().replaceAll("[" + row1 + "]", "").length() == 0 ||
        words[i].toLowerCase().replaceAll("[" + row2 + "]", "").length() == 0 ||
        words[i].toLowerCase().replaceAll("[" + row3 + "]", "").length() == 0) {
        if (words[i] != null) {
         resultWithNull[counter] = words[i];
         ++counter;
       }
     }
   }

   String[] result = new String[counter];
   for (int i = 0 ; i < counter; i++) {
      result[i] = resultWithNull[i];
   }
   return result;
 }

}