将给定字符串的唯一字母添加到列表

Posted

技术标签:

【中文标题】将给定字符串的唯一字母添加到列表【英文标题】: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 来实现其内容的唯一性。 【参考方案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());

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

【讨论】:

以上是关于将给定字符串的唯一字母添加到列表的主要内容,如果未能解决你的问题,请参考以下文章

给定一个字符串列表,如果任何值等于列表中的值,我想将字典的值添加到新字典中[重复]

在字符串/列表中添加某些数字,然后变成字母

给定一个字符串,问是否能通过添加一个字母将其变为回文串。

389. 找不同

excel怎样根据给定的字符生成一个8位的随机字符

LeetCode第十七题-电话号码的字母组合