Program to read seven integer values and print out the number of occurrences of each value

Viewed 223

as the title suggests, i'm trying to input 7 integers and be able to output those integers along with a count for how many duplicates there were among them.

Using the code:

public static void main(String[] args) {
  Scanner input = new Scanner(System.in);
  int[] userInput = new int[7];
  System.out.print("Enter seven numbers: ");
  for (int i = 0; i < 7; i++) {
    userInput[i] = input.nextInt();
  }
  for (int i = 0; i < 7; i++) {
    int duplicates = 0;
    for (int j = 0; j < 7; j++) {
      if (userInput[i] == userInput[j])
        duplicates++;
    }
    System.out.println("Number " + userInput[i] + " occurs " + duplicates + " times.");
  }
}

with the input: 12 23 44 22 23 22 55

I keep getting duplicates in my output, like so:

Number 12 occurs 1 times.
Number 23 occurs 2 times.
Number 44 occurs 1 times.
Number 22 occurs 2 times.
Number 23 occurs 2 times.
Number 22 occurs 2 times.
Number 55 occurs 1 times.

For clarity, what i'm aiming for is:

Number 12 occurs 1 times.
Number 23 occurs 2 times.
Number 44 occurs 1 times.
Number 22 occurs 2 times.
Number 55 occurs 1 times

I appreciate any and all suggestions.

10 Answers

You can use a vector to store all occurs for each number

public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] userInput = new int[7];
System.out.print("Enter seven numbers: ");
for (int i = 0; i < 7; i++) {
  userInput[i] = input.nextInt();
}

int duplicates[] = new int[7];
for(int i = 0; i < 7; i++)
   duplicates[i] = 0;

for (int i = 0; i < 7; i++) {
  for (int j = 0; j < 7; j++) {
    if (userInput[i] == userInput[j])
      duplicates[i]++;
  }
  System.out.println("Number " + userInput[i] + " occurs " + duplicates[i] + " times.");
}
}

The output for the input 12 23 44 22 23 22 55 will be:

Number 23 occurs 2 times.
Number 44 occurs 1 times.
Number 22 occurs 2 times.
Number 23 occurs 2 times.
Number 22 occurs 2 times.
Number 55 occurs 1 times.
public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    int[] userInput = new int[7];
    System.out.print("Enter seven numbers: ");
    for (int i = 0; i < 7; i++) {
        userInput[i] = input.nextInt();
    }

    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int i : userInput) {
        if (map.containsKey(i))
            map.put(i, map.get(i) + 1);
        else
            map.put(i, 1);
    }

    for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
        System.out.println("Number " + entry.getKey() + " occurs " + entry.getValue() + " times.");
    }
}

Currently, the program calculates occurrence of each digit in an array and that's where duplicate digits its doing duplicate efforts.

There are different ways of achieving what you are trying to do, the straight forward way could be, store the numbers in a map, which key as number and value as 1, and increment whenever the same digit is encountered again.

There are couple of ways:

Using sorting:

    Arrays.sort(userInput);
    for(int i=0;i<userInput.length;){
     int count = 1;
     int j = i + 1;
     while(j < userInput.length && userInput[i] == userInput[j]{
      j++; count++;
    }
    
    System.out.println("Number "+userInput[i]+" occurs "+count +" times");
     i = j;
    }

This will reduce the time complexity to O(N log N)

you can further improve this till O(N) using HashMap

use HashMap

Map<Integer, Integer> hm = new HashMap<Integer, Integer>(); 
for (int i : userInput) {
    Integer j = hm.get(i); 
    hm.put(i, (j == null) ? 1 : j + 1); 
}

for (Map.Entry<Integer, Integer> val : hm.entrySet()) {
    System.out.println("Number " + val.getKey() + " occurs " + val.getValue() + " times.");
}

You can do the same By using HashMap<Integer, Integer> as shown below.

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    int[] userInput = new int[7];
    System.out.print("Enter seven numbers: ");
    for (int i = 0; i < 7; i++) {
        userInput[i] = input.nextInt();
    }

    HashMap<Integer, Integer> numberCountMap = new HashMap<>();
    for(int element : userInput){
        numberCountMap.put(element, (numberCountMap.containsKey(element)) ? numberCountMap.get(element) + 1 : 1);
    }
    numberCountMap.forEach((key, value) -> System.out.println("Number " + key + " occurs " + value + " times."));
}

My approach would be -

First of all to change j to j = i+1 because you dont need an extra iteration to confirm that array[i]==array[i].

Second thing is to store the results in a Map<digit , occurances> and print from the map at the end of the method.

for (int i = 0; i < 7; i++) {
int duplicates = 1;
for (int j = i+1; j < 7; j++) {
  if (userInput[i] == userInput[j])
    duplicates++;
}
map.put(i , duplicates);

It would be more efficient to store the numbers in a Map.

Assuming your input is 12 23 44 22 23 22 55

void duplicates(){
    
    //acquire input and store it in a List
    Scanner input = new Scanner(System.in);
    List<Integer> numbers = input.nextLine().split(" ");

    //store the values into a map
    HashMap<Integer, Integer> numbersMap = new HashMap<>();
    for(int number : numbers){
        //if the map contains the number already, then increase it's occurence by one
        //otherwise store it into the map with the value of 1
        int newValue = numbersMap.containsKey(number) ? numbersMap.get(number) + 1 : 1;
        numbersMap.put(number, newValue);
    }

    //print results
    numbersMap.forEach((k, v) -> {
        System.out.println(String.format("The number %d occured %d times.", k, v));
    });
}

You can implement this in a very clean way using streams:

import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class IntegerCounter {
    public static Map<Integer, Long> countOccurences(int[] input) {
        return Arrays.stream(input)
                .boxed()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    }
}

Here is a test case that demonstrates it's usage:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Map;

public class IntegerCounterTests {
    @Test
    public void shouldReturnCorrectCount() {
        int[] input = {12,23,44,22,23,22,55};
        Map<Integer, Long> expectedResult = Map.of(12, 1L, 23, 2L, 44, 1L, 22, 2L, 55, 1L);
        Map<Integer, Long> result = IntegerCounter.countOccurences(input);

        result
                .entrySet()
                .stream()
                .forEach(e -> System.out.println(String.format("Number %d occurs %d times.", e.getKey(), e.getValue())));

        Assertions.assertEquals(expectedResult, result);
    }
}

Next to an assertion to verify that the result is indeed what you want I also added the lines to show the output to standard out:

Number 22 occurs 2 times.
Number 55 occurs 1 times.
Number 23 occurs 2 times.
Number 44 occurs 1 times.
Number 12 occurs 1 times.

You already handled the hard part. The only thing you should do is, putting writed values to a list, and if list contains the next value, simply, not to write this value again this is your code : `

public static void main(String[] args) {
  Scanner input = new Scanner(System.in);
  int[] userInput = new int[7];
  System.out.print("Enter seven numbers: ");
  for (int i = 0; i < 7; i++) {
    userInput[i] = input.nextInt();
  }
  for (int i = 0; i < 7; i++) {
    int duplicates = 0;
    for (int j = 0; j < 7; j++) {
      if (userInput[i] == userInput[j])
        duplicates++;
    }
    System.out.println("Number " + userInput[i] + " occurs " + duplicates + " times.");
  }
}

`

and this is the code, i modified a bit

List<Integer> values = new ArrayList<>();       
public static void main(String[] args) {
      Scanner input = new Scanner(System.in);
      int[] userInput = new int[7];
      System.out.print("Enter seven numbers: ");
      for (int i = 0; i < 7; i++) {
        userInput[i] = input.nextInt();
      }
      for (int i = 0; i < 7; i++) {
            if(!values.contains(userInput[i]){
             int duplicates = 0;

                 for (int j = 0; j < 7; j++) {
                        if (userInput[i] == userInput[j])
                               duplicates++;
                               }
          System.out.println("Number " + userInput[i] + " occurs " + duplicates + " times.");
values.add(userInput[i]);
}
      }
    }

here, the list creation of me, can be wrong. But i think you got the idea. Good luck

Related