Duplicate output in Java

Viewed 167

I'm new here and still learning. Today I learn find duplicate in string. From https://www.javatpoint.com/program-to-find-the-duplicate-characters-in-a-string, I try to learn complete code from web.

When string = "Great responsibility" the output will be:

 Duplicate characters in a given string: 
r
e
t
s
i

because it has duplicate character r e t s i

And when string is "great" the output is

 Duplicate characters in a given string: 

The output is blank because there are no duplicate characters, so I give a description "no duplicate" to define no character duplicate and the output goes like this

Duplicate characters in a given string: 
no duplicates
no duplicates
no duplicates
no duplicates
no duplicates

This returns too many descriptions.

My code

public class DuplicateCharacters {  
    public static void main(String[] args) {  
        String string1 = "Great";  
        int count;  
          
        //Converts given string into character array  
        char string[] = string1.toCharArray();  
          
        System.out.println("Duplicate characters in a given string: ");  
        //Counts each character present in the string  
        for(int i = 0; i <string.length; i++) {  
            count = 1;  
            for(int j = i+1; j <string.length; j++) {  
                if(string[i] == string[j] && string[i] != ' ') {  
                    count++;  
                    //Set string[j] to 0 to avoid printing visited character  
                    string[j] = '0';  
                }  
            }  
            //A character is considered as duplicate if count is greater than 1  
            if(count > 1 && string[i] != '0')  
                System.out.println(string[i]);  
            else 
             System.out.println("no duplicates"); 
        }  
    }  
} 

How can I print only one description without repetition? I tried return 0; but it does not work.

Expected output

Duplicate characters in a given string: 
no duplicates
4 Answers

Separate the logic for finding duplicates from how you report the findings to the user. Move the logic for finding the duplicates into a method. Pass the results of that output to another method. The main method invokes the first and passes the output to the second.

public static void main(String[] args) {
  String s = .... whatever you are searching for duplicates in ....
  reportDuplicates(findDuplicates(s)):
}
public static List<Character> findDuplicates(String s) {
  ... returns a List containing duplicates ...
}
public static void reportDuplicates(List<Character> duplicates) {
  if (null == duplicates || duplicates.isEmpty()) {
    ... report no duplicates ...
  } else {
    ... output the duplicates
  }
}

Add a flag to your program that indicates whether there are duplicates or not. And after loop check whether this flag is true or false.

This method would look like below. I commented code where I updated it.

public static void main(String[] args) {
    String string1 = "Great";
    int count;

    //Converts given string into character array
    char string[] = string1.toCharArray();

    // here is flag added
    boolean noDuplicates = true;

    System.out.println("Duplicate characters in a given string: ");
    //Counts each character present in the string
    for(int i = 0; i <string.length; i++) {
      count = 1;
      for(int j = i+1; j <string.length; j++) {
        if(string[i] == string[j] && string[i] != ' ') {
          count++;
          //Set string[j] to 0 to avoid printing visited character
          string[j] = '0';
        }
      }
      //A character is considered as duplicate if count is greater than 1
      if(count > 1 && string[i] != '0') {
        System.out.println(string[i]);

        //here is flag updated if duplicates are found
        noDuplicates = false;
      }
    }

    //here is flag check
    if (noDuplicates) {
      System.out.println("no duplicates");
    }
  }

And btw. Your algorithm has O(n^2) time complexity. You can figure out one that is better ;-)

It's normal your System.out.println("no duplicates"); is in your loop so each time a character is not duplicate you print "no duplicates".

You can defined a boolean that will become true if one duplicate it's found, like this :

public class DuplicateCharacters {
public static void main(String[] args) {
    String string1 = "Great";
    int count;

    //Converts given string into character array
    char string[] = string1.toCharArray();

    System.out.println("Duplicate characters in a given string: ");
    //Counts each character present in the string
    Boolean dupCarac = false;
    for(int i = 0; i <string.length; i++) {
        count = 1;
        for(int j = i+1; j <string.length; j++) {
            if(string[i] == string[j] && string[i] != ' ') {
                count++;
                //Set string[j] to 0 to avoid printing visited character
                string[j] = '0';
            }
        }
        //A character is considered as duplicate if count is greater than 1
        if(count > 1 && string[i] != '0'){
            System.out.println(string[i]);
            dupCarac = true;
        }
    }
    if (!dupCarac){
        System.out.println("no duplicates");
    }
}

PS: Please put {} on your if and else.

You might find interesting the following approach of how you can do the same, using Streams more efficiently, without iterating through the same String multiple times.

String input =  "Great responsibility";

Map<String, Long > map = Arrays.stream(input.split(""))  //create a stream for each character in String
          .collect((Collectors.groupingBy(item -> item, Collectors.counting()))) //Collect into a map all occurrences
          .entrySet().stream().filter(e -> e.getValue() > 1 && !e.getKey().equals(" ")) //filter only duplicate occurrences and not empty spaces
          .map(e -> Map.entry(e.getKey(), e.getValue() -1)) // keep count only of duplicate occurrences not total occurrences
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); //gather duplicates in a map

        if (map.isEmpty()){
            System.out.println("No duplicates found");
        } else {
            map.forEach((key, value) -> System.out.printf("%s appears %d more times in given string%n", key, value));
        }
Related