【问题标题】:Add unique letters of a given String to a List将给定字符串的唯一字母添加到列表
【发布时间】:2016-03-22 17:51:32
【问题描述】:

我想将字符串的字母添加到列表中,但我只想将每个字母添加一次。例如,如果字符串是“HELLO AM CHRISTOS WHITE”,有些字母出现了不止一次,所以我希望它们只添加一次。

我正在考虑两个 for 循环:

for (int i=0; i< str.length(); i++){
    for(int j=0; j< str.length(); j++){
        if (str.charAt(i) != str.charAt(j)) {
            myList.add(charAt(i));
        }
    }
}

但是这段代码并没有避免重复。

【问题讨论】:

  • 为什么是两个循环?遍历单个 originalLine.toCharArray(); if ( !listContains(Char.valueOf(char[i])) addChar();
  • 或者,您可以使用Set 来实现其内容的唯一性。

标签: java loops for-loop arraylist


【解决方案1】:

使用LinkedHashSet 来确定唯一字符会更有效。如果使用LinkedHashSet,输入字符串的唯一字符的顺序将被保留。

在一个循环之后,这将花费线性时间,您可以将所有唯一字符添加到您的输出 List

Set<Character> unique = new LinkedHashSet<>();
for (int i = 0; i < str.length(); i++){
    unique.add(str.charAt(i));
}
myList.addAll(unique);

【讨论】:

    【解决方案2】:

    为了防止集合中出现重复,您不需要List,您需要Set(例如HashSet)。

    如果您想保留添加Strings 的顺序,请使用LinkedHashSet

    最后,如果您希望 Set 自然地对您的 Strings 进行排序(或者能够使用 Comparator 对其进行排序),请使用 TreeSet

    示例

    String foo = "ghghababcdef";
    Set<String> hash = new HashSet<>();
    Set<String> linked = new LinkedHashSet<>();
    Set<String> tree = new TreeSet<>();
    // iterating characters
    for (char c: foo.toCharArray()) {
        // adding String representation of character to each set
        hash.add(Character.toString(c));
        linked.add(Character.toString(c));
        tree.add(Character.toString(c));
    }
    // printing...
    System.out.println(hash);
    System.out.println(linked);
    System.out.println(tree);
    

    输出

    [a, b, c, d, e, f, g, h] // this may vary
    [g, h, a, b, c, d, e, f] // keeps insertion order
    [a, b, c, d, e, f, g, h] // sorted lexicographically by default
    

    【讨论】:

      【解决方案3】:

      如果您想坚持使用List 解决方案,可以替代Set 答案。 您只需要循环一次并使用List.contains(Object) 方法并检查当前char 是否已存在于您的List 中。

      String str = "HELLO AM CHRISTOS WHITE";
      List<Character> myList = new ArrayList<>();
      for(int i=0; i< str.length(); i++){
          if (!myList.contains(str.charAt(i))) {
              myList.add(str.charAt(i));
          }
      }
      for(char c : myList) {
          System.out.println(c);
      }
      

      输出

      HELO AMCRISTW

      【讨论】:

        【解决方案4】:

        j 未分配。我猜它被初始化为0所以没有例外

        如果您将第二个循环更改为for(int j=0; j&lt; str.length(); j++),它仍然无法工作,它不会打印字符串中重复的任何字母。

        所以想想 j 需要迭代什么范围。如果你明白我的意思,你想打印字符串中尚未出现的任何字母。

        【讨论】:

        • 这只是我程序中的一个例子是正确的。无论如何,这个问题被回答了。
        • @ChristosMichael:在这种情况下,接受最能回答您的问题的答案是个好主意。它可以帮助未来的访问者快速确定他们问题的有效解决方案。见What should I do when someone answers my question?
        • 我的回答是解决您提供的代码中的错误,我怎么知道您的程序中有什么。另外,我假设您想解决实现逻辑中的问题,但没有意识到您还有其他选择来使用众所周知的数据结构。
        【解决方案5】:

        不幸的是,Java 8 中没有字符流,但这是 Java 8 的一种方式:

        str.chars().distinct().mapToObj(c -> (char) c).collect(Collectors.toList());
        

        它可能效率较低,但它是一种可读的单行,它显示了流的力量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-31
          • 2014-12-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多