Как найти несколько минимумов в массиве

23 / 21 / 3

Регистрация: 27.10.2017

Сообщений: 192

1

Найти несколько минимальных элементов в массиве

16.05.2018, 19:04. Показов 6873. Ответов 13


Студворк — интернет-сервис помощи студентам

Дан массив, в нем есть k элементов, как найти 3,4,5…n минимальных элементов в массиве? Как найти конкретное число я знаю, а как иначе — нет…



0



13 / 13 / 16

Регистрация: 23.04.2018

Сообщений: 110

16.05.2018, 23:55

2

nikita55050505, что? Разве минимальных может быть несколько(если только число не повторяется)?



0



16 / 15 / 13

Регистрация: 20.11.2017

Сообщений: 100

17.05.2018, 00:02

3

вам надо найти индексы всех минимальных элементов?



0



D3m1an

296 / 227 / 102

Регистрация: 11.08.2016

Сообщений: 780

17.05.2018, 00:47

4

Можно попробовать так, но есть пару нюансов. .

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
 
#define K       10
#define N       5       //количество минимальных
 
unsigned int arr[K] = {23,1,56,7,89,9,0,4,777,65535};
 
unsigned int findMinimal(unsigned int leastDig);
 
int main(void)
{
    int minCount = 0;
    unsigned int min[N] = {0};.  //Массив N количества искомых
    #define I (minCount == 0) ? minCount: minCount-1
    
    int temp;
    //запись N минимальных в массив min
    for(int i = 0; i < N; i++)
    {
        min[minCount] = findMinimal(min[I]);
        
        minCount++;
    }
    
    //вывод
    printf("String of numbers:n");
    for(int i = 0; i < K; i++)
        printf("%d ", arr[i]);
    printf("nn%d minimal numbers:n", N);
    for(int i = 0; i < minCount; i++)
    {
        printf("%d. %un", i, min[i]);
    }
    return 0;
}
 
 
unsigned int findMinimal(unsigned int leastDig)
{
    unsigned int tmp = ~(0);     //выставить все биты 
    int i = 0;
    while(i < K)
    {
        //если текущее число меньше tmp и больше ранее найденого, то запишем новое
        if(arr[i] <= tmp && arr[i] > leastDig)
        {
            tmp = arr[i];
        }
        i++;
    }
    return tmp;
}



0



Eanmos

698 / 140 / 57

Регистрация: 20.08.2017

Сообщений: 255

17.05.2018, 07:08

5

Думаю, проще всего будет сначала отсортировать массив, а потом уже выводить минимальные элементы.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define SWAP(x, y) do { x ^= y; y ^= x; x ^= y; } while (0)
 
void gnome_sort(int* a, size_t size) {
    for (size_t i = 0; i < size-1; ++i) {
        if (a[i] > a[i+1]) {
            SWAP(a[i], a[i+1]);
            (i >= 1) ? i -= 2 : --i;
        }
    }
}
 
int main(int argc, char const *argv[]) {
    int arr[] = {10, -1, 3, 0, 2, 1, 2, 19, 13, 9, 7, 7};
 
    gnome_sort(arr, sizeof(arr) / sizeof(int));
 
    for (size_t i = 0; i < N; ++i)
        printf("%d ", arr[i]);
}

Вместо N подставляете кол-во минимальных элементов. Гномью сортировку можно заменить любую другую.



0



woldemas

654 / 458 / 212

Регистрация: 06.09.2013

Сообщений: 1,266

17.05.2018, 07:38

6

nikita55050505

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
 
int main()
{
 
    int arr[] = {23,1,56,7,89,9,0,4,777,65535};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    int k = 3; // Количество минимумов 
    int mins[k + 1]; // Массив для их хранения (один вспомогательный)
    // Инициализация
    mins[0] = arr[0];
    // Поиск минимумов
    size_t d = 1; 
    for(size_t i = 0; i < n; i++) {
        size_t j = d;
        while(j > 0 && mins[j - 1] > arr[i]) {
            mins[j] = mins[j - 1];
            j--;
        }
        mins[j] = arr[i];
        if (d < k) d++;
    }
    // Вывод минимумов
    for(size_t i = 0; i < k; i++) {
        printf("%d ", mins[i]);
    }
    return 0;
}



0



artem312312

2 / 2 / 0

Регистрация: 17.02.2017

Сообщений: 117

27.05.2018, 11:22

7

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <stdio.h>
#include <stdlib.h>
 
#define K       10
#define N       5       //êîëè÷åñòâî ìèíèìàëüíûõ
 
void merge(unsigned int *a,  int n)
{
  int mid = n / 2; // íàõîäèì ñåðåäèíó ñîðòèðóåìîé ïîñëåäîâàòåëüíîñòè
  if (n % 2 == 1)
    mid++;
  int h = 1; // øàã
  // âûäåëÿåì ïàìÿòü ïîä ôîðìèðóåìóþ ïîñëåäîâàòåëüíîñòü
  int *c = new int [n];
  int step;
  while (h < n) 
  {
    step = h;
    int i = 0;   // èíäåêñ ïåðâîãî ïóòè
    int j = mid; // èíäåêñ âòîðîãî ïóòè
    int k = 0;   // èíäåêñ ýëåìåíòà â ðåçóëüòèðóþùåé ïîñëåäîâàòåëüíîñòè
    while (step <= mid) 
    {
      while ((i < step) && (j < n) && (j < (mid + step))) 
      { // ïîêà íå äîøëè äî êîíöà ïóòè
        // çàïîëíÿåì ñëåäóþùèé ýëåìåíò ôîðìèðóåìîé ïîñëåäîâàòåëüíîñòè
        // ìåíüøèì èç äâóõ ïðîñìàòðèâàåìûõ
        if (a[i] < a[j])  
        {
          c[k] = a[i];
          i++; k++;
        }
        else {
          c[k] = a[j];
          j++; k++;
        }
      }
      while (i < step) 
      { // ïåðåïèñûâàåì îñòàâøèåñÿ ýëåìåíòû ïåðâîãî ïóòè (åñëè âòîðîé êîí÷èëñÿ ðàíüøå)
        c[k] = a[i];
        i++; k++;
      }
      while ((j < (mid + step)) && (j<n)) 
      {  // ïåðåïèñûâàåì îñòàâøèåñÿ ýëåìåíòû âòîðîãî ïóòè (åñëè ïåðâûé êîí÷èëñÿ ðàíüøå)
        c[k] = a[j];
        j++; k++;
      }
      step = step + h; // ïåðåõîäèì ê ñëåäóþùåìó ýòàïó
    }
    h = h * 2;
    // Ïåðåíîñèì óïîðÿäî÷åííóþ ïîñëåäîâàòåëüíîñòü (ïðîìåæóòî÷íûé âàðèàíò) â èñõîäíûé ìàññèâ
    for (i = 0; i<n; i++)
      a[i] = c[i];
  }
}
 
unsigned int arr[K] = {23,1,56,7,89,9,2,4,777,65535};
 
unsigned int findMinimal(unsigned int leastDig);
 
int main(void)
{
    int minCount = 0;
    int p1=1;
    int p2=2, x;
    unsigned int min[N] = {0};  //Ìàññèâ N êîëè÷åñòâà èñêîìûõ
    #define I (minCount == 0) ? minCount: minCount-1
    
    int temp;
    //çàïèñü N ìèíèìàëüíûõ â ìàññèâ min
    scanf("%d", &x);
    if (x==1)
    {
    for(int i = 0; i < N; i++)
    {
        min[minCount] = findMinimal(min[I]);
        
        minCount++;
    }
      printf("String of numbers:n");
    for(int i = 0; i < K; i++)
        printf("%d ", arr[i]);
    printf("nn%d minimal numbers:n", N);
    for(int i = 0; i < minCount; i++)
    {
        printf("%d. %un", i, min[i]);
    }}
    else
    {
        merge(arr ,K); // ВОТ ЗДЕСЬ неправильно сортирует
  for (int i = 0; i<10; i++){
    printf("%d ", arr[i]);
    printf("n");}
 
    }
    
    //âûâîä
 
    return 0;
}
 
 
unsigned int findMinimal(unsigned int leastDig)
{
    unsigned int tmp = ~(0);     //
    int i = 0;
    while(i < K)
    {
        //
        if(arr[i] <= tmp && arr[i] > leastDig)
        {
            tmp = arr[i];
        }
        i++;
    }
    return tmp;
}

Задача состоит в том, что дан массив с консоли и нужно 1) найти k наим элементов, в пунтке 1 работает, и 2 сперва отсортировать и найти k наим элементов методом слияния и определить, что работает быстрее если в файле 1000 10000 100000 элементов, вот во 2-ом методе в данном коде сортировка работает неверно, не знаете почему?

Добавлено через 12 минут
и ещё, кто-то знает что делает эта строка?

C
1
 #define I (minCount == 0) ? minCount: minCount-1



0



296 / 227 / 102

Регистрация: 11.08.2016

Сообщений: 780

27.05.2018, 11:30

8

artem312312,

Цитата
Сообщение от artem312312
Посмотреть сообщение

и ещё, кто-то знает что делает эта строка?
#define I (minCount == 0) ? minCount: minCount-1

Макроопределение I . Подстановка вместо I в коде строки «(minCount == 0) ? minCount: minCount-1», что в свою очередь аналогично оператору «if» — Если minCount равен 0, то вернуть значение minCount, в противном случае вернуть minCount-1



0



artem312312

2 / 2 / 0

Регистрация: 17.02.2017

Сообщений: 117

27.05.2018, 11:54

9

C
1
  unsigned int tmp = ~0;

А это? зачем тут побитовое не? и можно ли заменить?

Цитата
Сообщение от D3m1an
Посмотреть сообщение

что в свою очередь аналогично оператору «if» — Если minCount равен 0, то вернуть значение minCount, в противном случае вернуть minCount-1

Если переписать как if то оно чет не работает, ну или я не то делаю скорее всего

Добавлено через 15 минут

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdio.h>
#include <stdlib.h>
 
#define K       10
#define N       5       //количество минимальных
 
void merge(int*a, int n)
{
    int rght, rend, b[20];
    int i, j, m;
 
    for (int k = 1; k < n; k *= 2)
    {
        for (int left = 0; left + k < n; left += k * 2)
        {
            rght = left + k;
            rend = rght + k;
            if (rend > n) rend = n;
            m = left; i = left; j = rght;
            while (i < rght && j < rend)
            {
                if (a[i] <= a[j])
                {
                    b[m] = a[i]; i++;
                }
                else
                {
                    b[m] = a[j]; j++;
                }
                m++;
            }
            while (i < rght)
            {
                b[m] = a[i];
                i++; m++;
            }
            while (j < rend)
            {
                b[m] = a[j];
                j++; m++;
            }
            for (m = left; m < rend; m++)
            {
                a[m] = b[m];
            }
        }
    }
}
 
 int arr[K] = {23,1,56,7,89,9,2,4,777,65535};
 
unsigned int findMinimal(unsigned int leastDig);
 
int main(void)
{
    int minCount = 0;
    int p1=1;
    int p2=2, x;
    unsigned int min[N] = {0};  //Массив N количества искомых
    #define I (minCount == 0) ? minCount: minCount-1
    
    int temp;
    //запись N минимальных в массив min
    scanf("%d", &x);
    if (x==1)
    {
    for(int i = 0; i < N; i++)
    {
        min[minCount] = findMinimal(min[I]);
        
        minCount++;
    }
      printf("String of numbers:n");
    for(int i = 0; i < K; i++)
        printf("%d ", arr[i]);
    printf("nn%d minimal numbers:n", N);
    for(int i = 0; i < minCount; i++)
    {
        printf("%d. %un", i, min[i]);
    }}
    else
    {
        merge(arr ,K); // ????? ??????? ??????????
  // ????? ????????? ??????? ????? ??????????
    for(int i = 0; i < N; i++)
    {
        min[minCount] = findMinimal(min[I]);
        
        minCount++;
    }
      printf("String of numbers:n");
    for(int i = 0; i < K; i++)
        printf("%d ", arr[i]);
    printf("nn%d minimal numbers:n", N);
    for(int i = 0; i < minCount; i++)
    {
        printf("%d. %un", i, min[i]);
    }
 
    }
    
    //вывод
 
    return 0;
}
 
 
unsigned int findMinimal(unsigned int leastDig)
{
    unsigned int tmp = ~(0);     //выставить все биты 
    int i = 0;
    while(i < K)
    {
        //если текущее число меньше tmp и больше ранее найденого, то запишем новое
        if(arr[i] <= tmp && arr[i] > leastDig)
        {
            tmp = arr[i];
        }
        i++;
    }
    return tmp;
}

Исправил код, теперь работает как надо, но можете прокомментировать алгоритм этой функции?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
unsigned int findMinimal(unsigned int leastDig)
{
    unsigned int tmp = ~(0);    
    int i = 0;
    while(i < K)
    {
        
        if(arr[i] <= tmp && arr[i] > leastDig)
        {
            tmp = arr[i];
        }
        i++;
    }
    return tmp;
}



0



D3m1an

296 / 227 / 102

Регистрация: 11.08.2016

Сообщений: 780

27.05.2018, 12:09

10

Что значит побитовое НЕ ? Такого оператора нет.
Есть логический оператор НЕ — » ! »
«~» — побитовое ОТРИЦАНИЕ. Унарный оператор.

Цитата
Сообщение от D3m1an
Посмотреть сообщение

unsigned int tmp = ~(0); //выставить все биты

И собственно… выставить все биты в данном типе переменной . Инверсия 0 (~0b…0000 = 0b…1111).

Добавлено через 9 минут

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Возвращает минимальное число из массива arr, с учётом младшего числа leastDig
unsigned int findMinimal(unsigned int leastDig)         
{
    unsigned int tmp = ~(0);     //выставить все биты 
    int i = 0;
    while(i < K)
    {
        //если текущее число меньше tmp и больше ранее найденого, то запишем новое
        if(arr[i] <= tmp && arr[i] > leastDig)
        {
            tmp = arr[i];
        }
        i++;
    }
    return tmp;

Программа сканирует 1 раз массив сравнивая текущее минимальное число leastDig с числом из массива.

Вызывая её N раз, мы ищем N минимальных чисел из массива, не забывая отправлять предыдущее старшее число из уже найденых.



0



2 / 2 / 0

Регистрация: 17.02.2017

Сообщений: 117

27.05.2018, 17:35

11

Ещё небольшой вопрос, он ищет минимальные элементы правильно, но только положительных чисел, а если у меня будет -1, то не работает, как можно исправить?

Добавлено через 4 часа 36 минут

Цитата
Сообщение от D3m1an
Посмотреть сообщение

Можно попробовать так, но есть пару нюансов. .

Наверное ты как раз про это и говорил?



0



296 / 227 / 102

Регистрация: 11.08.2016

Сообщений: 780

27.05.2018, 19:03

12

artem312312, так точно.
Если отрицательные числа обязательны, то программу нужно модернизировать



0



2 / 2 / 0

Регистрация: 17.02.2017

Сообщений: 117

28.05.2018, 12:42

13

Да, отрицательные тоже нужны, но я так и не понял как их взять в диапазон

Добавлено через 13 часов 20 минут
If (arr[i]<0 || arr[i] <= tmp && arr[i] > leastDig)сделал так и убрал ~0 но все равно не проверяет, почему?

Добавлено через 3 часа 12 минут
Или это из-за unsigned?



0



D3m1an

296 / 227 / 102

Регистрация: 11.08.2016

Сообщений: 780

29.05.2018, 09:12

14

Конечно из-за типа unsigned int.

Удалять ~0 не стоит в данном случае программы. Иначе мы ничего не найдем. Этим действием мы добиваемся максимального числа.

Добавлено через 1 час 51 минуту
Попробуйте такой вариант

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
 
#define K       10
#define N       5       //количество минимальных
 
long long arr[K] = {23,1,56,-7,89,9,0,4,777,-65534};
 
long long findMinimal(long long leastDig);
 
int main(void)
{
    int minCount = 0;
    long long min[N] = {1 << 31};  //Массив N количества искомых
    #define I (minCount == 0) ? minCount: minCount-1
    
    //запись N минимальных в массив min
    for(int i = 0; i < N; i++, minCount++)
        min[minCount] = findMinimal(min[I]);
    
    
    //вывод
    printf("String of numbers:n");
    for(int i = 0; i < K; i++)
        printf("%lld ", arr[i]);
    
    printf("nn%d minimal numbers:n", N);
    for(int i = 0; i < minCount; i++)
    {
        printf("%d. %lldn", i, min[i]);
    }
    return 0;
}
 
 
long long findMinimal(long long leastDig)
{
    long long tmp = ~(1 << 31);//получить макс.число
    int i = 0;
    while(i < K)
    {
        //если текущее число меньше tmp и больше ранее найденого, то запишем новое
        if(arr[i] <= tmp && arr[i] > leastDig)
            tmp = arr[i];
        i++;
    }
    return tmp;
}



0



Необходимо найти два min значения в массиве случайных числе.
Код написан под swift.

var list = [Int] ()
var n: Int = 8

for i in 1...n
{
   let list = Int(arc4random_uniform(70))
   print (list)
}

func getMin1Min2(numbers:Int...) -> (min1:Int, min2:Int)
{
var min1 = numbers[0]
var min2 = numbers[0]

for number in numbers
{
if number < min1 {min1 = number}

Дальше попытка найти 2-ое минимальное значение, но увы

if number > min1
        {if number < min2
            {min2 = number}
        }
}
return (min1, min2)
}

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

var value = getMin1Min2 (list)

задан 28 мая 2016 в 18:08

mrSpaceDandy's user avatar

1

Для начала, Вы не заполняете массив. Вот создаете массив:

let n = 8
var arr = [Int]()
for _ in 0..<n {
    arr.append(Int(arc4random_uniform(70)))
}
print(arr)

Далее ищете 2 минимальных элемента в массиве, предлагаю просто отсортировать массив по возрастанию и возвращать первые 2 элемента:

func getMin1Min2(numbers:[Int]) -> (min1:Int, min2:Int){
    let sortedNumbers = numbers.sort({$0 < $1})
    return sortedNumbers.count > 1 ? (sortedNumbers[0], sortedNumbers[1]) : (sortedNumbers[0], sortedNumbers[0])
}

И проверка:

print(getMin1Min2(arr))

ответ дан 29 мая 2016 в 5:05

VAndrJ's user avatar

VAndrJVAndrJ

15.8k1 золотой знак18 серебряных знаков35 бронзовых знаков

Вариант 1: сделай копию массива, найди в нем минимум и удали его. Потом найди минимум еще раз.
Для не очень больших массивов подойдет.

Вариант 2: находишь первый минимум (запоминаешь его индекс).
Еще раз ищешь минимум в массиве, но уже не сравниваешь элемент с найденным индексом.

var myMin = MAX_INT
for i in 0..myArray.count {
    if (myArray[i] < myMin && i != indexOfFirstMin ){
        myMin = myArray[i]
    }
}

Denis's user avatar

Denis

8,86010 золотых знаков30 серебряных знаков55 бронзовых знаков

ответ дан 14 июн 2016 в 12:18

Валентин's user avatar

ВалентинВалентин

1,1056 серебряных знаков6 бронзовых знаков

0

Найти два наименьших (минимальных) элемента массива

Просмотров 7.7к. Обновлено 15 октября 2021

В одномерном массиве целых чисел определить два наименьших элемента. Они могут быть как равны между собой (оба являться минимальными), так и различаться.

Сначала можно найти минимальный элемент массива. После этого искать второй минимум, исключив их поиска первый с помощью if. Данный способ рассматривается здесь по отношению к двум наибольшим элементам.

Сложнее задачу решить, используя один цикл перебора.

Предположим, что двумя наименьшими элементами массива являются первый и второй элемент. Присвоим их индексы переменным m1 и m2. При этом, если первый элемент меньше второго, то его индекс присвоим m1, иначе m1 получит значение второго элемента, а m2 первого.

Начнем перебирать массив в цикле, начиная с третьего элемента. Если он меньше элемента, чей индекс хранится в m1, то присвоим индекс текущего элемента m1. Иначе (если значение по индексу m1 меньше, чем по индексу i) будем проверять, не меньше ли значение по индексу i, того что по индексу m2.

Есть один не очевидный нюанс. Допустим, в m1 указывало на значение 5, а m2 — на 10. Очередной элемент равен 3. Мы меняем m1, и забываем о числе 5. Однако оно может оказаться как раз вторым минимумом массива.

Поэтому в программе при изменении значения m1 надо предусмотреть проверку, не меньше ли теряемое значение, чем то, что хранится по индексу m2.

Pascal


const
N = 10;
var
a: array[1..N] of integer;
i, min1, min2, buff: byte;
begin
randomize;
for i:=1 to N do begin
a[i] := random(100);
write(a[i]:4);
end;
writeln;

if a[1] < a[2] then begin
min1 := 1;
min2 := 2;
end
else begin
min1 := 2;
min2 := 1;
end;

for i:=3 to N do
if a[i] < a[min1] then begin
buff := min1;
min1 := i;
if a[buff] < a[min2] then
min2 := buff;
end
else
if a[i] < a[min2] then
min2 := i;

writeln('№', min1:2,': ', a[min1]:2);
writeln('№', min2:2,': ', a[min2]:2);
end.



8 66 40 40 0 14 50 74 93 71
№ 5: 0
№ 1: 8

Язык Си


#include < stdio.h>
#define N 10
main() {
int a[N];
int i, min1, min2, buff;
srand(time(NULL));
for (i=0; i< N; i++) {
a[i] = rand() % 100;
printf("%3d", a[i]);
}
printf("n");

if (a[0] < a[1]) {
min1 = 0;
min2 = 1;
} else {
min1 = 1;
min2 = 0;
}

for (i=2; i< N; i++) {
if (a[i] < a[min1]) {
buff = min1;
min1 = i;
if (a[buff] < a[min2]) min2 = buff;
} else {
if (a[i] < a[min2]) min2 = i;
}
}

printf("№%2d:%3dn",min1+1,a[min1]);
printf("№%2d:%3dn",min2+1,a[min2]);
}



97 20 88 29 20 43 87 19 33 26
№ 8: 19
№ 5: 20

Python

найти два минимальных элемента массива python


from random import random
N = 10
a = []
for i in range(N):
a.append(int(random()*100))
print("%3d" % a[i], end='')
print()

if a[0] > a[1]:
min1 = 0
min2 = 1
else:
min1 = 1
min2 = 0

for i in range(2,N):
if a[i] < a[min1]:
b = min1
min1 = i
if a[b] < a[min2]:
min2 = b
elif a[i] < a[min2]:
min2 = i

print("№%3d:%3d" % (min1+1, a[min1]))
print("№%3d:%3d" % (min2+1, a[min2]))

# Вариант 2

from random import randint

array = [randint(1, 20) for i in range(10)]
print(array)

min1 = min(array)
array.remove(min1)
min2 = min(array)

print(min1)
print(min2)



14 3 40 56 42 43 89 69 64 72
№ 1: 14
№ 2: 3

КуМир


алг два минимальных
нач
цел N = 10
цел таб arr[1:N]
цел i,m1,m2,b
нц для i от 1 до N
arr[i] := irand(10,100)
вывод arr[i]:3
кц
вывод нс

если arr[1] < arr[2] то
m1 := 1
m2 := 2
иначе
m1 := 2
m2 := 1
все

нц для i от 3 до N
если arr[i] < arr[m1] то
b := m1
m1 := i
если arr[b] < arr[m2] то
m2 := b
все
иначе
если arr[i] < arr[m2] то
m2 := i
все
все
кц
вывод "№",m1:2,":",arr[m1]:3,нс
вывод "№",m2:2,":",arr[m2]:3,нс
кон



65 32 24 86 65 58 67 55 33 96
№ 3: 24
№ 2: 32

Basic-256


N = 10
dim arr(N)
for i=0 to N-1
arr[i] = int(rand*100)
print arr[i] + " ";
next i
print

if arr[0] < arr[1] then
m1 = 0
m2 = 1
else
m1 = 1
m2 = 0
endif

for i=2 to N-1
if arr[i] < arr[m1] then
b = m1
m1 = i
if arr[b] < arr[m2] then
m2 = b
endif
else
if arr[i] < arr[m2] then
m2 = i
endif
endif
next i

print (m1+1) + ": " + arr[m1]
print (m2+1) + ": " + arr[m2]



81 7 25 71 23 9 56 91 73 64
2: 7
6: 9

Improve Article

Save Article

Like Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Like Article

    Find the first, second and third minimum elements in an array in O(n).

    Examples: 

    Input : 9 4 12 6
    Output : First min = 4
             Second min = 6
             Third min = 9
    
    Input : 4 9 1 32 12
    Output : First min = 1
             Second min = 4
             Third min = 9

    First approach : First we can use normal method that is sort the array and then print first, second and third element of the array. Time complexity of this solution is O(n Log n).

    C++

    #include<bits/stdc++.h>

    using namespace std;

    int Print3Smallest(int array[], int n)

    {

        sort(array,array+n);

        cout << "First min = " << array[0] << "n";

        cout << "Second min = " << array[1] << "n";

        cout << "Third min = " << array[2] << "n";

    }

    int main()

    {

        int array[] = {4, 9, 1, 32, 12};

        int n = sizeof(array) / sizeof(array[0]);

        Print3Smallest(array, n);

        return 0;

    }

    Java

    import java.util.Arrays;

    public class Main {

      static void Print3Smallest(int array[], int n) {

      Arrays.sort(array);

          System.out.println("First min = " + array[0]);

          System.out.println("Second min = " + array[1]);

          System.out.println("Third min = " + array[2]);

      }

      public static void main(String[] args) {

          int array[] = {4, 9, 1, 32, 12};

          int n = array.length;

          Print3Smallest(array, n);

      }

    }

    Python3

    def print_3_smallest(array):

        array.sort()

        print("First min =", array[0])

        print("Second min =", array[1])

        print("Third min =", array[2])

    if __name__ == '__main__':

        array = [4, 9, 1, 32, 12]

        n = len(array)

        print_3_smallest(array)

    C#

    using System;

    using System.Linq;

    class Program

    {

        static void Print3Smallest(int[] array, int n)

        {

            Array.Sort(array);

            Console.WriteLine("First min = " + array[0]);

            Console.WriteLine("Second min = " + array[1]);

            Console.WriteLine("Third min = " + array[2]);

        }

        static void Main()

        {

            int[] array = {4, 9, 1, 32, 12};

            int n = array.Length;

            Print3Smallest(array, n);

        }

    }

    Javascript

    function Print3Smallest(array,n){

        array.sort((a, b) => a - b);

        console.log('First min = ' + array[0]);

        console.log('Second min = ' + array[1]);

        console.log('Third min = ' + array[2]);

    }

    let array = [4, 9, 1, 32, 12];

    Print3Smallest(array,array.length);

    Output

    First min = 1
    Second min = 4
    Third min = 9

    Second approach : Time complexity of this solution is O(n).

    Algorithm:

    • First take an element
    • then if array[index] < Firstelement
      • Thirdelement = Secondelement
      • Secondelement = Firstelement
      • Firstelement = array[index]
    •      else if array[index] < Secondelement
      •   Thirdelement = Secondelement
      •  Secondelement = array[index]
    •      else if array[index] < Thirdelement
      • Thirdelement = array[index]
    • then print all the element 

    Implementation:

    C++

    #include<bits/stdc++.h>

    #define MAX 100000

    using namespace std;

    int Print3Smallest(int array[], int n)

    {

        int firstmin = MAX, secmin = MAX, thirdmin = MAX;

        for (int i = 0; i < n; i++)

        {

            if (array[i] < firstmin)

            {

                thirdmin = secmin;

                secmin = firstmin;

                firstmin = array[i];

            }

            else if (array[i] < secmin)

            {

                thirdmin = secmin;

                secmin = array[i];

            }

            else if (array[i] < thirdmin)

                thirdmin = array[i];

        }

        cout << "First min = " << firstmin << "n";

        cout << "Second min = " << secmin << "n";

        cout << "Third min = " << thirdmin << "n";

    }

    int main()

    {

        int array[] = {4, 9, 1, 32, 12};

        int n = sizeof(array) / sizeof(array[0]);

        Print3Smallest(array, n);

        return 0;

    }

    Java

    import java.util.*;

    public class GFG

    {

        static void Print3Smallest(int array[], int n)

        {

                int firstmin = Integer.MAX_VALUE;

                int secmin = Integer.MAX_VALUE;

                int thirdmin = Integer.MAX_VALUE;

                for (int i = 0; i < n; i++)

                {

                    if (array[i] < firstmin)

                    {

                        thirdmin = secmin;

                        secmin = firstmin;

                        firstmin = array[i];

                    }

                    else if (array[i] < secmin)

                    {

                        thirdmin = secmin;

                        secmin = array[i];

                    }

                    else if (array[i] < thirdmin)

                        thirdmin = array[i];

                }

                System.out.println("First min = " + firstmin );

                System.out.println("Second min = " + secmin );

                System.out.println("Third min = " + thirdmin );

        }

        public static void main(String[] args)

        {

                int array[] = {4, 9, 1, 32, 12};

                int n = array.length;

                Print3Smallest(array, n);

        }

    }

    Python3

    MAX = 100000

    def Print3Smallest(arr, n):

        firstmin = MAX

        secmin = MAX

        thirdmin = MAX

        for i in range(0, n):

            if arr[i] < firstmin:

                thirdmin = secmin

                secmin = firstmin

                firstmin = arr[i]

            elif arr[i] < secmin:

                thirdmin = secmin

                secmin = arr[i]

            elif arr[i] < thirdmin:

                thirdmin = arr[i]

        print("First min = ", firstmin)

        print("Second min = ", secmin)

        print("Third min = ", thirdmin)

    arr = [4, 9, 1, 32, 12]

    n = len(arr)

    Print3Smallest(arr, n)

    C#

    using System;

    class GFG

    {

    static void Print3Smallest(int []array, int n)

        {

                int firstmin = int.MaxValue;

                int secmin = int.MaxValue;

                int thirdmin = int.MaxValue;

                for (int i = 0; i < n; i++)

                {

                    if (array[i] < firstmin)

                    {

                        thirdmin = secmin;

                        secmin = firstmin;

                        firstmin = array[i];

                    }

                    else if (array[i] < secmin)

                    {

                        thirdmin = secmin;

                        secmin = array[i];

                    }

                    else if (array[i] < thirdmin)

                        thirdmin = array[i];

                }

                Console.WriteLine("First min = " + firstmin );

                Console.WriteLine("Second min = " + secmin );

                Console.WriteLine("Third min = " + thirdmin );

        }

        static void Main()

        {

        int []array = new int[]{4, 9, 1, 32, 12};

        int n = array.Length;

        Print3Smallest(array, n);

        }

    }

    PHP

    <?php

    function Print3Smallest($array, $n)

    {

        $MAX = 100000;

        $firstmin = $MAX;

        $secmin = $MAX;

        $thirdmin = $MAX;

        for ($i = 0; $i < $n; $i++)

        {

            if ($array[$i] < $firstmin)

            {

                $thirdmin = $secmin;

                $secmin = $firstmin;

                $firstmin = $array[$i];

            }

            else if ($array[$i] < $secmin)

            {

                $thirdmin = $secmin;

                $secmin = $array[$i];

            }

            else if ($array[$i] < $thirdmin)

                $thirdmin = $array[$i];

        }

        echo "First min = ".$firstmin."n";

        echo "Second min = ".$secmin."n";

        echo "Third min = ".$thirdmin."n";

    }

        $array= array(4, 9, 1, 32, 12);

        $n = sizeof($array) / sizeof($array[0]);

        Print3Smallest($array, $n);

    ?>

    Javascript

    <script>

    let MAX = 100000

    function Print3Smallest( array,  n)

    {

        let firstmin = MAX, secmin = MAX, thirdmin = MAX;

        for (let i = 0; i < n; i++)

        {

            if (array[i] < firstmin)

            {

                thirdmin = secmin;

                secmin = firstmin;

                firstmin = array[i];

            }

            else if (array[i] < secmin)

            {

                thirdmin = secmin;

                secmin = array[i];

            }

            else if (array[i] < thirdmin)

                thirdmin = array[i];

        }

        document.write("First min = " + firstmin + "</br>");

        document.write("Second min = " + secmin + "</br>");

        document.write("Third min = " + thirdmin + "</br>");

    }

        let array = [4, 9, 1, 32, 12];

        let n = array.length;

        Print3Smallest(array, n);

    </script>

    Output

    First min = 1
    Second min = 4
    Third min = 9

    Time Complexity: O(n)
    Auxiliary Space: O(1)

    Last Updated :
    09 Mar, 2023

    Like Article

    Save Article

    Без сортировки задача может быть решена, например, так. Создаем рабочий массив длины m и заполняем его начальными значениями. В общем случае можно в качестве такого значения выбрать минимальное значение int/integer для соответствующей среды программирования. А если известна нижняя граница значений исходного массива, то можно взять любое число, меньшее этой границы.

    Итак рабочий массив заполнен одинаковыми значениями. Теперь берем элемент за элементом исходного массива и вставляем его в нужное место рабочего массива. При этом длину рабочего массива сохраняем равной m (после вставки последний элемент пропадает). Если очередной элемент меньше последнего значения рабочего массива, то он просто пропускается. Этот процесс имеет вычислительную сложность O(nm). Тогда как сортировка в лучшем случае описывается асимптотикой O(n*og(n)). Асимптотики показывают, как ведет себя функция (в данном случае — время сортировки) при стремлении параметров к бесконечности. Можно сказать, что время описанного алгоритма при стремлении n к бесконечности задается формулой t1=k1*O(n), а время сортировки t2=k2*O(n*log(n)). Здесь k1 и k2 — некие константы, зависящие от процессора, языка программирования, операционной системы и других факторов.

    Я построил три системы тестов (для Питона, Java и VBA). Все тесты устроены по сути одинаково: строились массивы возрастающих размеров, заполнялись случайными числами задаваемого диапазона, сортировались с фиксацией времени и прогонялись через описанный выше алгоритм тоже с фиксацией времени. Каждый тест повторялся 10 раз и время усреднялось. В Питоне и Java использовалась встроенная сортировка, в VBA — реализация QuickSort.

    Питон

    Ниже показан код питоновских тестов.

    import time
    from random import randint
        
    def max_n_1(arr,n):
        return sorted(arr,reverse=True)[0:n]
        
    def max_n_2(arr,n):
        res=[-1 for _ in range(n)]
        for x in arr:
            if x > res[n-1]:
                i=n-1
                j=i-1
                while(j>=0 and res[j]<x):
                    res[i]=res[j]
                    i=i-1
                    j=j-1
                res[i]=x
        return res  
        
    def start():
        k=10
        n=10000
        print("k=",k)
        while(n<=500000):
            print("n=",n,end=' ')
    
            t1=0.0
            for i in range(10):
                arr=[randint(1,2000) for _ in range(n)]
                start_time = time.time()
                z1=max_n_1(arr,k)
                fin_time = time.time()
                t1=t1+(fin_time-start_time)
            print(t1/10.0,end=' ')
        
            t2=0.0
            for i in range(10): 
                arr=[randint(1,2000) for _ in range(n)]
                start_time = time.time()
                z2=max_n_2(arr,k)
                fin_time = time.time()
                t2=t2+(fin_time-start_time)
            print(t2/10.0)
        
            n+=10000
            
    start()
    

    Размеры массива менялись от 10 до 500 тыс. элементов с шагом 10 тыс. Было выполнено два прогона: определение пяти и десяти максимумов. Результат для 10 максимумов показан ниже.

    Время здесь приведено в миллисекундах. Что видим? Сортировка отстает (на краю интервала — вдвое). Для пяти максимумов картина аналогична. И надо заметить, что хотя питоновская сортировка очень эффективна, простой алгоритм оказывается быстрее. Заметны резкие провалы в производительности (зубцы на графиках). Они, вероятно, объясняются влиянием внутренних процессов (типа сборки мусора). Это же замечание относится и к другим графикам.

    Java

    Код тестов выглядел так:

    import java.util.*;
    
    class Start
    {
       public static void main(String [] args)
       {   
        Random random = new Random();
        Scanner inp = new Scanner(System.in);
        long startTime,endTime,tot1,tot2;
        int i,a,b,n,m,x,ii,jj,u;
    	
        a=1;
        b=3000; // диапазон случайных чисел [a,b]
        m=10;
        
        System.out.println(a+" "+b+" "+m);
        for (n=50000; n<=5000000; n+=50000)
        {
    	    int arr[] = new int[n];
          int ma[]  = new int[m];
    	
          tot1=0;
          for (u=0; u<10; u++)
          {        
    	      for (i=0; i<n; i++)
    	      {
    		     arr[i]=a+random.nextInt(b-a+1);
    	      }
            startTime = System.currentTimeMillis();
            Arrays.sort(arr);
            endTime = System.currentTimeMillis();
            tot1=tot1+(endTime-startTime);
          }
    
          tot2=0;
          for (u=0; u<10; u++)
          {        
    	      for (i=0; i<n; i++)
    	      {
    		      arr[i]=a+random.nextInt(b-a+1);
    	      }
       
            startTime = System.currentTimeMillis();
    	      for (i=0; i<m; i++) ma[i]=-999999;
    	      for (i=0; i<n; i++)
    	      {
                x=arr[i];        
                if (x >= ma[m-1])
                {
                  ii=m-1;
                  jj=ii-1;
                  while(jj>=0 && ma[jj]<x)
                  {
                    ma[ii]=ma[jj];
                    ii--;
                    jj--;
                  }  
                  ma[ii]=x;
                }
              }
              endTime = System.currentTimeMillis();
              tot2=tot2+(endTime-startTime);
            }
          System.out.println(n+" "+tot1+" "+tot2); 	
      	}
      } 
    }

    Здесь размер массива тоже менялся от 10 тыс. до 500 тыс. элементов. Время — в миллисекундах. Результат оказался весьма похожим на питоновский (только сортировка Javа, увы, медленнее).

    VBA

    В этом языке нет универсальной встроенной сортировки (можно, правда, сортировать ячейки листа, но в этом случае будут велики накладные расходы, связанные с загрузкой и выгрузкой данных). Поэтому пришлось реализовать QuickSort вручную. Все это выглядит так:

    Private Declare Function GetTickCount Lib "kernel32" () As Long
    
    '::: Собственно сортировка
    Sub QSort(A() As Long, Optional b As Long = 1, Optional e As Long = 0)
        If b > e Then Exit Sub
        i& = b
        j& = e
        w& = A((i& + j&) / 2)
        Do While (True)
          Do While (A(i&) < w&)
             i& = i& + 1
          Loop
          Do While (A(j&) > w&)
             j& = j& - 1
          Loop
          If i& <= j& Then
             Tmp& = A(i&)
             A(i&) = A(j&)
             A(j&) = Tmp&
             i& = i& + 1
             j& = j& - 1
          End If
          If i& > j& Then Exit Do
        Loop
        
        If j& > b Then QSort A, b, j&
        If i& < e Then QSort A, i&, e
    
    End Sub
    
    '::: Проверка успешности сортировки 
    Function check(X() As Long) As Boolean
         n& = UBound(X)
         For i& = 1 To n& - 1
             If X(i& + 1) < X(i&) Then
                Debug.Print "Err! i=" + CStr(i&)
                check = False
                Exit Function
             End If
         Next i&
         check = True
    End Function
    
    '::: Вставка в упорядоченный массив
    Sub ins_in_arr(X As Long, A() As Long, n As Integer)
        If X < A(n) Then Exit Sub
        For i% = 1 To n
            If X > A(i%) Then
               For j% = n To i% + 1 Step -1
                   A(j%) = A(j% - 1)
               Next j%
               A(i%) = X
               Exit Sub
            End If
        Next i%
    End Sub
    
    '::: Собственно тест
    Sub test()
    Const sz = 500
    Dim X() As Long
    Dim Ma(1 To sz) As Long
        Randomize
        ooo& = 1
    
        For n& = 10000 To 500000 Step 10000
            
            t1# = 0
            For nc% = 1 To 10
                        
                ReDim X(1 To n&) As Long
                For i& = 1 To n&
                    X(i&) = Rnd() * 5000
                Next i&
                s1& = GetTickCount
                For i& = 1 To sz
                    Ma(i&) = -2147483647
                Next i&
                For i& = 1 To n&
                    ins_in_arr X(i&), Ma, 10
                Next i&
                s2& = GetTickCount
                t1# = t1# + s2& - s1&
            
            Next nc%
                    
            Cells(ooo&, 1).Value = n&
            Cells(ooo&, 2).Value = t1# / 10
                    
            t2# = 0
            
            For nc% = 1 To 10
            
                ReDim X(1 To n&) As Long
                For i& = 1 To n&
                    X(i&) = Rnd() * 5000
                Next i&
                s1& = GetTickCount
                QSort X, 1, n&
                s2& = GetTickCount
                If Not check(X) Then
                   MsgBox "Ошибка при сортировке!"
                   Exit Sub
                End If
                t2# = t2# + s2& - s1&
    
            Next nc%
    
            Cells(ooo&, 3).Value = t2# / 10
            ooo& = ooo& + 1
            
        Next n&
    
    End Sub

    На каждом витке цикла корректность сортировки проверяется. Время проверки, естественно, не включается в общий хронометраж. Набор исходных данных тот же — от 10 до 500 тыс. целых чисел. Получает, в общем, похожая картина:

    Представляет некоторый интерес изучить зависимость времени от количества искомых максимумов (при фиксированном размере массива). Здесь, очевидно, сортировка будет тем выгоднее, чем больше максимумов требуется найти. А вставка в упорядоченный массив будет тем медленнее, чем массив больше.

    Самым невыгодным случаем будет являться, как ни странно, входной массив, уже упорядоченный по возрастанию. В этом случае количество сравнений при вставке достигнет максимума и будет равно n*m. Массив, упорядоченный по убыванию, напротив, весьма выгоден. Число сравнений здесь будет ~ m+n.

    Описанный в самом начале статьи алгоритм, можно ускорить, если вместо простого упорядоченного массива использовать древовидную или пирамидальную структуру. Именно так и реализована в Питоне в модуле heapq функция nsmallest.

    Для небольших массивов (несколько тысяч элементов и менее) разница в подходах представляется несущественной. И если нужно быстро написать код, то сортировка — вполне приемлемое решение. Для больших массивов выгоднее от сортировки отказаться.

    Вот и все, что я хотел рассказать об этой задаче. Спасибо, что дочитали до конца. С наступившим 2021-м годом!

    Понравилась статья? Поделить с друзьями:
  • Как найти сиделку по уходу за больным
  • Как найти корень в слове объяснить
  • Как найти льющую форсунку на дизеле
  • Как на ноутбуке найти плейлист
  • Райсен как найти доспехи