Программа для чтения семи целых значений и распечатки количества вхождений каждого значения

#java #arrays

#java #массивы

Вопрос:

как следует из названия, я пытаюсь ввести 7 целых чисел и иметь возможность выводить эти целые числа вместе с подсчетом количества дубликатов среди них.

Используя код:

 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.");
  }
}
  

с вводом: 12 23 44 22 23 22 55

Я продолжаю получать дубликаты в своих выходных данных, например:

 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.
  

Для ясности, к чему я стремлюсь, это:

 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
  

Я ценю любые предложения.

Комментарии:

1. Можете ли вы использовать Map или это домашнее задание, и вам предписано использовать только массивы?

2. вы можете использовать hashmap для хранения дубликатов…

3. Вау, спасибо вам всем за такой быстрый ответ. Это задание, и мы не рассматривали карты или потоки, или что-либо, кроме основ. У меня создается впечатление, что я мог бы использовать только массивы.

Ответ №1:

Вы можете использовать вектор для хранения всех вхождений для каждого числа

 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.");
}
}
  

Вывод для ввода 12 23 44 22 23 22 55 будет:

 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.
  

Ответ №2:

 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.");
    }
}
  

Ответ №3:

В настоящее время программа вычисляет вхождение каждой цифры в массиве, и именно там повторяющиеся цифры выполняют дублирующие усилия.

Существуют разные способы достижения того, что вы пытаетесь сделать, прямым способом может быть сохранение чисел на карте, ключ которой как число и значение как 1, и увеличение всякий раз, когда одна и та же цифра встречается снова.

Ответ №4:

Есть несколько способов:

Использование сортировки:

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

Это уменьшит временную сложность до O (N log N)

вы можете дополнительно улучшить это до O (N), используя HashMap

Ответ №5:

используйте 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.");
}
  

Ответ №6:

Вы можете сделать то же самое, используя HashMap<Целое число, целое число>, как показано ниже.

 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."));
}
  

Ответ №7:

Мой подход был бы —

Прежде всего, чтобы изменить j j = i 1 , потому что вам не нужна дополнительная итерация для подтверждения этого array[i]==array[i] .

Второе — сохранить результаты в a Map<digit , occurances> и распечатать с карты в конце метода.

 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);
  

Ответ №8:

Было бы более эффективно хранить числа в a Map .

Предполагая, что ваш ввод 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));
    });
}
  

Комментарии:

1. Для придирок: да, подход lambda / stream можно и нужно использовать и в части хранения, но я вообще не хотел вдаваться в лямбды и потоки, пока не понял, что мне придется повторять HashMap с помощью итератора, чему я рад, что избавился от своеготеперь голова.

Ответ №9:

Вы можете реализовать это очень простым способом, используя потоки:

 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()));
    }
}
  

Вот тестовый пример, который демонстрирует его использование:

 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);
    }
}
  

Рядом с утверждением, чтобы убедиться, что результат действительно тот, который вы хотите, я также добавил строки, чтобы показать вывод в 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.
  

Ответ №10:

Вы уже справились с трудной частью. Единственное, что вам нужно сделать, это поместить записанные значения в список, и если список содержит следующее значение, просто не записывать это значение снова, это ваш код: `

 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.");
  }
}
  

`

и это код, который я немного изменил

 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]);
}
      }
    }
  

здесь, создание списка мной, может быть неправильным. Но я думаю, вы поняли идею.
Удачи