Java:在字符串中打印唯一字符

8
我正在编写一个程序,它将打印字符串中的唯一字符(通过扫描器输入)。我创建了一个方法来尝试完成这个任务,但我一直得到不是重复字符的字符,而不是字符串中唯一的字符(或字符)。我只想要独特的字母。
这是我的代码:
import java.util.Scanner;
public class Sameness{
   public static void main (String[]args){
   Scanner kb = new Scanner (System.in); 
     String word = "";

     System.out.println("Enter a word: ");
     word = kb.nextLine();

     uniqueCharacters(word); 
}

    public static void uniqueCharacters(String test){
      String temp = "";
         for (int i = 0; i < test.length(); i++){
            if (temp.indexOf(test.charAt(i)) == - 1){
               temp = temp + test.charAt(i);
         }
      }

    System.out.println(temp + " ");

   }
}            

以下是使用上述代码的示例输出:

Enter a word: 
nreena
nrea 

预期输出应为:ra

“nreena”的预期输出是什么? - developer
1
但是 e 是一个重复的字符,你仍然在输出中得到了它。你期望的输出是 ra 吗? - RaminS
无论如何,我会像这样做 char[] array = test.toCharArray(); 然后循环遍历 array 中的每个字母,如果没有匹配项,则执行 temp = temp + test.charAt(i); - RaminS
是的,期望的输出应该是“ra”。 - Dextra
一旦您添加了一个字符,即使找到它的多个出现,也不会删除现有的字符。 - Naman
20个回答

10

根据您想要的输出结果,您需要替换一个字符,该字符在后面出现重复时已经被添加了,因此:

public static void uniqueCharacters(String test){
    String temp = "";
    for (int i = 0; i < test.length(); i++){
        char current = test.charAt(i);
        if (temp.indexOf(current) < 0){
            temp = temp + current;
        } else {
            temp = temp.replace(String.valueOf(current), "");
        }
    }

    System.out.println(temp + " ");

}

1
这很高效 - Allen
非常感谢你! - Dextra
需要else块吗? - Suree
@Suree,这是必需的。基本上,“else”块正在删除一个最初被视为唯一的字符,但一旦发现它被重复,就应该将其删除。 - lmiguelvargasf
@lmiguelvargasf,实际上else块会删除temp中每个第二次出现的字符。temp.indexOf(current)也会检查在temp字符串中最初被视为唯一的字符。因此,没有必要使用else块。我已经检查过了。 - Suree

10

如何考虑使用KISS原则:

public static void uniqueCharacters(String test) {
    System.out.println(test.chars().distinct().mapToObj(c -> String.valueOf((char)c)).collect(Collectors.joining()));
}

与上面的解决方案相比,这是最佳答案,具有最少的执行时间。 - MobileEvangelist

3

接受的答案并不能通过所有测试用例,例如:

输入 -"aaabcdd"

期望输出-"bc"
但是接受的答案会给出 -abc

这是因为字符a出现了奇数次。

在这里,我使用了ConcurrentHashMap来存储字符及其出现次数,然后如果出现次数超过一次,就删除该字符。

import java.util.concurrent.ConcurrentHashMap;

public class RemoveConductive {

    public static void main(String[] args) {

        String s="aabcddkkbghff";

        String[] cvrtar=s.trim().split("");

        ConcurrentHashMap<String,Integer> hm=new ConcurrentHashMap<>();
        for(int i=0;i<cvrtar.length;i++){
            if(!hm.containsKey(cvrtar[i])){
                hm.put(cvrtar[i],1);
            }
            else{
                 hm.put(cvrtar[i],hm.get(cvrtar[i])+1);
            }
        }
        for(String ele:hm.keySet()){
            if(hm.get(ele)>1){
                hm.remove(ele);
            }
        }
        for(String key:hm.keySet()){
            System.out.print(key);
        }
    }  
}

2

虽然为了解决问题,我建议您尝试使用更好的数据结构而不仅仅是字符串。但是,您可以通过使用以下的else修改逻辑来删除已经存在的重复项:

public static void uniqueCharacters(String test) {
        String temp = "";
        for (int i = 0; i < test.length(); i++) {
            char ch = test.charAt(i);
            if (temp.indexOf(ch) == -1) {
                temp = temp + ch;
            } else {
                temp.replace(String.valueOf(ch),""); // added this to your existing code
            }
        }

        System.out.println(temp + " ");

    }

1
看起来很有趣,但我的答案和你的几乎完全相同,只是变量名改变了。虽然我在可以使用它的时候使用了这个变量,也就是说,我没有重复使用 test.charAt(i) 超过一次。 - lmiguelvargasf
正确的做法不应该重复使用它。我只是试图优化OP的代码,错过了这一点。 - Naman

1
这是一个面试问题。找出字符串中所有独特的字符。 以下是完整的解决方案。代码本身就很清楚易懂。
public class Test12 {
    public static void main(String[] args) {
        String a = "ProtijayiGiniGina";

        allunique(a);
    }

    private static void allunique(String a) {
        int[] count = new int[256];// taking count of characters
        for (int i = 0; i < a.length(); i++) {
            char ch = a.charAt(i);
            count[ch]++;
        }

        for (int i = 0; i < a.length(); i++) {
            char chh = a.charAt(i);
            // character which has arrived only one time in the string will be printed out
            if (count[chh] == 1) {
                System.out.println("index => " + i + " and unique character => " + a.charAt(i));

            }
        }

    }// unique

}

在Python中:

def firstUniqChar(a):
    count = [0] *256
    for i in a: count[ord(i)] += 1
    element = ""

    for item in a:
        if (count[ord(item)] == 1):
            element = item;
            break;
    return element        


a = "GiniGinaProtijayi";
print(firstUniqChar(a)) # output is P

1
public static String input = "10 5 5 10 6 6 2 3 1 3 4 5 3";

public static void uniqueValue (String numbers) {
    String [] str = input.split(" ");
    Set <String> unique = new HashSet <String> (Arrays.asList(str));
    System.out.println(unique);

    for (String value:unique) {
        int count = 0;
        for ( int i= 0; i<str.length; i++) {
            if (value.equals(str[i])) {
                count++;
            }
        }
        System.out.println(value+"\t"+count);
    }
}
public static void main(String [] args) {
    uniqueValue(input);
}

1
步骤1:为了找到字符串中的唯一字符,我首先从用户那里获取了字符串。 步骤2:使用Java中的内置函数将输入字符串转换为charArray。 步骤3:考虑两个HashSet(set1用于存储所有字符,即使它重复了,set2用于仅存储唯一字符)。 步骤4:在数组上运行for循环,并检查如果特定字符不在set1中,则将其添加到set1和set2中。如果该特定字符已经存在于set1中,则将其再次添加到set1中,但从set2中删除它。(当特定字符出现奇数次时,else部分很有用)。 步骤5:现在set2只包含唯一字符。因此,只需打印该set2即可。
public static void main(String[] args)
{
    Scanner input = new Scanner(System.in);
    String str = input.next();
    char arr[] = str.toCharArray();
    
    HashSet<Character> set1=new HashSet<Character>();
    HashSet<Character> set2=new HashSet<Character>();

    
    for(char i:arr)
    {
        if(set1.contains(i))
        {
            set1.add(i);
            set2.remove(i);
            
        }
        else
        {
            
            set1.add(i);
            set2.add(i);
        }
    }
    
    System.out.println(set2); 

}

0

如果您不想使用额外的空间:

    String abc="developer";

    System.out.println("The unique characters are-");

    for(int i=0;i<abc.length();i++)
    {
        for(int j=i+1;j<abc.length();j++)
        {
            if(abc.charAt(i)==abc.charAt(j))
                abc=abc.replace(String.valueOf(abc.charAt(j))," ");
        }
    }   
    System.out.println(abc);

时间复杂度为O(n^2),不占用额外空间。


0
import java.util.*;
import java.lang.*;
class Demo
{
public static void main(String[] args)
{

Scanner sc=new Scanner(System.in);
System.out.println("Enter String");
String s1=sc.nextLine();
 try{
HashSet<Object> h=new HashSet<Object>();
for(int i=0;i<s1.length();i++)
{
h.add(s1.charAt(i));
}
Iterator<Object> itr=h.iterator();
  while(itr.hasNext()){
   System.out.println(itr.next());
    }
    }
    catch(Exception e)
    {
    System.out.println("error");
    }
}
}

1
你能添加一些解释吗?谢谢! - MLavrentyev
HashSet不支持重复值。我将每个字符添加到HashSet中,这样重复项就会自动解决。 - Siddhivinayak Shanbhag

0
public static void main(String[] args) {
    String s = "aaabcdd";
    char a[] = s.toCharArray();
    List duplicates = new ArrayList();
    List uniqueElements = new ArrayList();
    for (int i = 0; i < a.length; i++) {
        uniqueElements.add(a[i]);
        for (int j = i + 1; j < a.length; j++) {
            if (a[i] == a[j]) {
                duplicates.add(a[i]);
                break;
            }
        }
    }
    uniqueElements.removeAll(duplicates);
    System.out.println(uniqueElements);
    System.out.println("First Unique : "+uniqueElements.get(0));

}

输出: [b,c] 第一个唯一的元素:b


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接