WedX - журнал о программировании и компьютерных науках

Поиск нескольких мод в массиве

Я пытаюсь написать метод Java, который находит все режимы в массиве. Я знаю, что есть простой способ найти режим в массиве, но когда есть более одного режима, мой метод выводит только один из них. Я пытался найти способ, но не уверен, как подойти к этой проблеме. Может ли кто-нибудь помочь мне найти все режимы в массиве? Спасибо.

Да, вот мой код, который выводит только один режим, даже если существует несколько режимов.

public static int mode(int a[]){
  int maxValue=0, maxCount=0;   
  for (int i = 0; i < a.length; ++i){
    int count = 0;
    for (int j = 0; j < a.length; ++j){
      if (a[j] == a[i]) ++count;
    }
    if (count > maxCount){
      maxCount = count;
      maxValue = a[i];
    }
  }
  return maxValue;
}

хорошо вот например: 30 30 30 34 34 23

В этом наборе чисел есть только одна мода — 30.

30 30 30 34 34 34 23

Но в этом наборе есть два режима, 30 и 34. Я хочу, чтобы мой код мог выводить оба из них, тогда как он печатает только один. Печатает только 30.

13.01.2012

  • Что вы имеете в виду под режимом? Что это за простой способ найти режим в массиве, на который вы ссылаетесь. Любой код вашего метода, который выводит только один из них? 14.01.2012
  • да, вот мой код, который выводит только один режим, даже если существует более одного. открытый статический режим int (int a []) { int maxValue = 0, maxCount = 0; for (int i = 0; i ‹ a.length; ++i) { int count = 0; for (int j = 0; j ‹ a.length; ++j) { if (a[j] == a[i]) ++count; } if (count › maxCount) { maxCount = count; максимальное значение = а[я]; } } вернуть maxValue; } 14.01.2012
  • @Daniel, не добавляйте код в комментарии; просто отредактируйте свой вопрос. 14.01.2012
  • да извините что переделал. 14.01.2012
  • И какова связь между этим фрагментом кода и вашим вопросом? Этот код просто возвращает int, который чаще всего встречается в массиве, в то время как вы хотите «найти несколько режимов» в массиве. Вы имеете в виду, что хотите вернуть массив без дубликатов? Это объясняется здесь. Если вы имеете в виду что-то другое, пожалуйста, уточните свой вопрос 14.01.2012
  • @Robin - вот что такое mode - элемент в массиве (набор в математической терминологии), который встречается чаще всего. В случае равенства, когда 2 элемента появляются одинаковое количество раз, массив равен bimodal, а если более 2 элементов появляются одинаковое количество раз, multimodal 14.01.2012
  • @BrianRoach большое спасибо, теперь я наконец понял вопрос 14.01.2012
  • да, у меня есть массив с более чем одним режимом, и я хочу распечатать их все. 14.01.2012

Ответы:


1

Следующий код вернет вам Integer[], содержащий режимы. Если вместо этого вам нужен int[], вам все равно нужно вручную преобразовать экземпляры Integer в int. Вероятно, не самая эффективная версия, но она точно соответствует вашему коду.

public static Integer[] mode(int a[]){
  List<Integer> modes = new ArrayList<Integer>(  );
  int maxCount=0;   
  for (int i = 0; i < a.length; ++i){
    int count = 0;
    for (int j = 0; j < a.length; ++j){
      if (a[j] == a[i]) ++count;
    }
    if (count > maxCount){
      maxCount = count;
      modes.clear();
      modes.add( a[i] );
    } else if ( count == maxCount ){
      modes.add( a[i] );
    }
  }
  return modes.toArray( new Integer[modes.size()] );
}
13.01.2012
  • Да, вы в значительной степени заперты в O (n ^ 2). Единственная оптимизация, о которой я могу думать, это если бы вы использовали maxCount для ограничения внутреннего цикла; если ((j.length - (j + 1)) + count) < maxCount вы можете внести залог. 14.01.2012

  • 2

    После долгой ночи программирования я, наконец, получил программу, которая распечатывает режим/режимы массива. Или даже сообщит вам, если режима нет (скажем, если ни один ввод не произошел более одного раза или все вводы произошли одинаковое количество раз: например, 1, 1, 2, 2, 3, 3, 4, 4 ). Некоторые ограничения программы заключаются в том, что вы должны ввести более одного числа, и вы не можете ввести более 10000 чисел или отрицательное число (если вы хотите ввести отрицательное число, вам просто нужно настроить все циклы for, включающие значения [][] Массив. Некоторые интересные вещи в моей программе заключаются в том, что она распечатывает, сколько раз каждый из вас вводил данные вместе с режимом вашего массива. И все распечатки грамматики меняются в зависимости от количества информации (пример. Режим вашего массива 2. Режимы вашего массива 1 и 2. Режимы вашего массива 0, 2, 5 и 8. В программе также есть пример функции пузырьковой сортировки для тех, кто думал, что им нужна была функция сортировки в их программе режима. Надеюсь, это поможет, я включил много псевдокода, чтобы помочь всем, кто не видит, как моя логика продвигается по всей программе (к вашему сведению: это Java, и он был скомпилирован в BlueJ).

    import java.util.Scanner;
    public class Mode
    {
        public static void main (String args [])
        {
            Scanner scan = new Scanner(System.in);
            int MAX_INPUTS = 10000; boolean flag = false;
            System.out.print ("Input the size of your array: ");
            int size; // How many nubers will be in the user array
            do
            {
                size = scan.nextInt();
                if (size == 1)
                {
                    System.out.print ("\nError. You must enter a number more than 1.\n\n"); 
                    continue;
                }
                else if (size > MAX_INPUTS || size < 0)
                {
                    System.out.print ("\nError. You muste enter a number less than " + MAX_INPUTS + " or greater than 0\n\n");
                    continue;
                }
                else
                    flag = true; // a ligit answer has been entered.
            }
            while (flag != true);
            int array[] = new int[size], values[][] = new int[2][MAX_INPUTS + 1], ticks = 0;
    
            System.out.print ("\nNow input the numbers for your array.\n\n");
    
            /* Taking inputs from the user */        
            while (ticks < size)
            {
                System.out.print ("Number " + (ticks + 1) + ": ");
                array[ticks] = scan.nextInt();
                if (array[ticks] > MAX_INPUTS || array[ticks] < 0)
                {
                    System.out.print ("\nError. Number cannot be greater than " + MAX_INPUTS + " or less than 0\n\n");
                    continue;
                }               
                ++ticks;
            }
    
            /* 
             * values[][] array will hold the info for how many times numbers 0 - 10000 appear in array[]. Column 0 will hold numbers from 0 -1000, and column 1 will hold the number of
             * of repititions the number in column 0 occured in the users inputed array.
             */
    
            for (int i = 0; i < MAX_INPUTS; ++i) // Initalize Column zero with numbers starting at zeor, and ending and MAX_INPUTS.
                values[0][i] = i;
    
            for (int i = 0; i < size; ++i) // Find the repatitions of the numbers in array[] that correspond to the number in column zere of values[][].
                for (int j = 0; j < MAX_INPUTS; ++j)
                    if (array[i] == j)
                        ++values[1][j];
    
            sort (array, size);
            System.out.print ("\n\nHere are the numbers you entered.\n\n"); // show the values the user entered in ascending order.
    
            for (int i = 0; i < size; ++i)
            {
                if (i == size - 1) // the last inputed number
                    System.out.print (array[i]); // don't allow an extra comma.
                else
                    System.out.print (array[i] + ", ");
            }
    
            // Show the user how many times each of the values he/she entered occured.
    
            System.out.print ("\n\nThis is the amount of times each of the values you entered occured:\n");
    
            for (int i = 0; i < MAX_INPUTS; ++i)
            {
                if (values[1][i] == 1)
                    System.out.print (i + " was entered " + values[1][i] + " time\n"); // avoid: 2 was entered 1 times
                else if (values[1][i] != 0)
                    System.out.print (i + " was entered " + values[1][i] + " times\n"); // avoid: 2 was entered 2 time
            }
    
    
            /* -------------------------------------------------------------------- | Finding the Mode/Modes | -------------------------------------------------------------------- */
            /* The process begins with creating a second array that is the exactly the same as the values[][] (First for loop). Then I sort the duplicate[] array to find the mode 
             * (highest number in the duplicate[]/values[][] arrays. Int max is then assigned the highest number. Remembering that the values[][] array: column 0 contains numbers ranging
             * from 1 to 10000, it keeps track of where the numbers in column were originally located, in which you can compare to the duplicate array which is sorted. Then I can set 
             * up a flag that tells you whether there is more than one mode. If so, the printing of these modes will look neater and the grammar can be changed accordingly.
             */
    
            int duplicate[] = new int [10001], mode[] = new int [size], max, mode_counter = 0;
            boolean multi_mode = false, all_same;
    
            for (int i = 0; i < MAX_INPUTS; ++i)
                duplicate[i] = values[1][i]; // copy values array.
    
            sort (duplicate, MAX_INPUTS);
            max = duplicate[MAX_INPUTS - 1]; // the last number in the sorted array is the greatest.
            all_same = test (duplicate, MAX_INPUTS, size, max); // this is the test to see if all the numbers in the user array occured the same amount of times.
            int c = 0; // a counter
    
            /* The mode of the user inputed array will be recorded in the values array. The sort of the duplicate array told me what was the higest number in that array. Now I can 
             * see where that highest number used to be in the original values array and recored the corresponding number in the column zero, which was only filled with numbers 0 -
             * 10000. Thus telling me the mode/modes.
             */
    
            for (int i = 0; i < MAX_INPUTS; ++i)
            {
                if (values[1][i] == max)
                {
                    mode[c++] = values[0][i];
                    ++mode_counter;
                }
            }
    
            if (mode[1] != 0) //mode[0] (the first cell, has a number stored from the last for loop. If the second cell has a number other than zero, that tells me there is more than 1 mode.
                multi_mode = true;
    
            if (multi_mode == false)
                System.out.print ("\nThe mode of your array is " + mode[0]); // For correct grammer.
            else if (all_same == true)
                System.out.print ("\nAll of the numbers entered appeared the same amount of times. "); // See the boolean function for more details
            else // If here there is more than one mode.
            {
                System.out.print ("\nThe modes of yoru array are ");
                for (int i = 0; i < mode_counter; ++i)
                {
                    if (mode_counter > 2 && i == (mode_counter - 1))  // If there is more than two modes and the final mode is to be printed.
                        System.out.print ("& " + mode[i]);
                    else if (mode_counter == 2)
                    { // This is true if there is two modes. The else clause will print the first number, and this will print the amper sign and the second mode.
                        System.out.print (mode[0] + " & " + mode[1]); 
                        break;
                    }
                    else
                        System.out.print (mode[i] + ", ");
                }
            }
        }
    
        public static void sort (int list[], int max) // Its the bubble sort if you're wondering.
        {
            int place, count, temp;        
            for (place = 0; place < max; ++place)
                for (count = max - 1; count > place; --count)
                    if (list[count - 1] > list[count])
                    {
                            temp = list[count-1];
                            list[count - 1] = list[count];
                            list[count] = temp;
                    }
        }
    
        /* The test to see if there isn't a mode. If the amount of the mode number is the same as the amount of numbers there are in the array is true, or if the size entered by the 
         * user (input) modulo the mode value is equal to zero (say, all the numbers in an array of ten were entered twice: 1, 1, 2, 2, 3, 3, 4, 4, 5, 5). */
        public static boolean test (int list[], int limit, int input, int max)
        {
            int counter = 0, anti_counter = 0;
            for (int i = 0; i < limit; ++i)
                if (list[i] == max)
                    ++counter; // count the potential modes
                else if (list[i] !=0 && list[i] != max)
                    ++anti_counter; // count every thing else except zeros.
    
    
            if (counter == input || (input % max == 0 && anti_counter == 0) )
                return true;
            else
                return false;
        }
    }
    
    09.09.2012

    3

    Хотя это, вероятно, не самое эффективное решение, оно будет печатать все самые высокие режимы:

    public static int mode(int a[]) {
        int maxValue=-1, maxCount=0;
        for (int i = 0; i < a.length; i++) {
            int count = 0;
            for (int j = 0; j < a.length; j++) {
                if (a[j] == a[i])
                    count++;
                }
            }
            if (count > maxCount) {
                maxCount = count;
                maxValue = a[i];
            }
        }
    
        //loop again and print only the highest modes
        for (int i = 0; i < a.length; i++) {
            int count = 0;
            for (int j = 0; j < a.length; j++) {
                if (a[j] == a[i])
                    count++;
                }
            }
            if (count == maxCount) {
                System.out.println(a[i]);
            }
        }
    }
    
    13.01.2012
  • Скажи что ... это не будет иметь никакого значения 14.01.2012
  • вы правы, это просто делает то же самое, что и мой предыдущий код. 14.01.2012
  • Обновил мое решение. Это сработает сейчас. Не уверен, что вы просто хотели их распечатать или вернуть. Это решение печатает их. 14.01.2012
  • это решение печатает режимы столько раз, сколько они встречаются, тогда как я хочу, чтобы они печатались только один раз. Спасибо, хотя теперь у меня есть общее представление о том, как работает этот код. 14.01.2012

  • 4

    Надеюсь это поможет. Это мой ответ. Надеюсь, поможет

    public List mode(double[] m) {
        HashMap<Double, Double> freqs = new HashMap<Double, Double>();
        for (double d : m) {
            Double freq = freqs.get(d);
            freqs.put(d, (freq == null ? 1 : freq + 1));
        }
        List<Double> mode = new ArrayList<Double>();
        List<Double> frequency = new ArrayList<Double>();
        List<Double> values = new ArrayList<Double>();
    
        for (Map.Entry<Double, Double> entry : freqs.entrySet()) {
            frequency.add(entry.getValue());
            values.add(entry.getKey());
        }
        double max = Collections.max(frequency);
    
        for(int i=0; i< frequency.size();i++)
        {
            double val =frequency.get(i);
            if(max == val )
            {
                mode.add(values.get(i));
            }
        }
        return mode;
    }
    
    19.04.2013
    Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

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

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]