Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
213 / 160 / 52
Регистрация: 09.12.2017
Сообщений: 520
1

Заполнить массив числами без повторов в диапазоне [a,b]

18.02.2019, 17:02. Просмотров 3228. Ответов 10


Вот условие : заполнить массив числами без повторов в диапазоне [a,b].
Вот как решил это я :
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
#include <iostream>
#include <ctime>
 
void GenerateNonRepetitiveArray(int length, int *arr, int a, int b) 
{
    for (int i = 0; i < length; i++)
        arr[i] = a + i;
 
    int random_index = rand() % length;
    int temp;
    for (int i = 0; i < length; i++)
    {
        temp = arr[i];
        arr[i] = arr[random_index];
        arr[random_index] = temp;
    }
}
 
void PrintArray(int length, int *arr)
{
    for (int i = 0; i < length; i++)
        std::cout << " " << arr[i];
    std::cout << std::endl;
}
 
int main()
{
    srand(time(NULL));
 
    using std::cout;
    using std::endl;
    using std::cin;
 
    int length; cout << " Enter length of the array here : "; cin >> length;
    int *arr = new int[length];
 
    cout << " Enter range [a,b] : " << endl;
    int a, b;
    do {
        cout << " Enter a = "; cin >> a;
        cout << " Enter b = "; cin >> b;
        if ((b - a + 1) < length)
            cout << " Error ! \n B-A >= length of the first array " << endl;
    } while ((b - a + 1) < length);
 
    GenerateNonRepetitiveArray(length, arr, a, b);
    PrintArray(length, arr);
 
    return 0;
}
Идея моего решения : заполняем массив его индексами + а (т.к. а - "старт" диапазона) и перемешиваем его в случайном порядке. При вводе а и b я проверяю следующее : (b - a + 1) < размер_массива. Это исключает возможные ошибки.
Например :
Код
размер = 5
а = 1
b = 3
...
Тут будет ошибка , т.к. не получиться сгенерировать 5 чисел без повторов в таком диапазоне.
Проверка выше позволяет с этим бороться.

Меня интересует, можно ли решить это лучше. Критика кода приветствуется. Спасибо !
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.02.2019, 17:02
Ответы с готовыми решениями:

Поровну заполнить массив числами в диапазоне 0-1
Нужно чтобы в массиве нулей было столько же сколько и единиц, причем порядок должен быть случайным

Заполнить массив случайными числами в диапазоне
Помогите, пожалуйста, найти ошибку :( Нужно заполнить двумерный массив случайными простыми...

Заполнить массив нечётными числами в диапазоне от -10 до 30 по возрастанию
Заполнить массив нечётными числами в диапазоне от -10 до 30 по возрастанию. код С++ : #include...

Заполнить массив заданного размера нечётными числами в указанном диапазоне
Заполнить массив из 50-ти элементов нечётными числами от 1 до 99. нужно использовать остаток от...

__________________
Помогаю в написании студенческих работ здесь.
Записывайтесь на профессиональные курсы C++ разработчиков
10
1533 / 780 / 321
Регистрация: 11.10.2018
Сообщений: 4,087
18.02.2019, 17:11 2
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
C++
1
int random_index = rand()%length;
- почему рандомный номер 1 раз генерируется, может быть лучше было бы что бы при каждой итерации цикла в строке 11 рандомный номер был каждый раз новый?
1
213 / 160 / 52
Регистрация: 09.12.2017
Сообщений: 520
18.02.2019, 17:17  [ТС] 3
FFPowerMan, думаю, Ваша правка справедлива.
C++
1
2
3
4
5
6
7
8
9
int random_index;
int temp;
for (int i = 0; i < length; i++)
{
    random_index = rand() % length;
    temp = arr[i];
    arr[i] = arr[random_index];
    arr[random_index] = temp;
}
Добавлено через 1 минуту
Есть еще предложения ?
0
443 / 329 / 172
Регистрация: 01.07.2015
Сообщений: 1,162
18.02.2019, 19:56 4
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
Есть еще предложения ?
использовать нормальный генератор случайных чисел. rand() плохо справляется в зависимости от платформы с большими числами

+ можно заменить всю эту канитель на стандартную функцию shuffle
1
33 / 32 / 9
Регистрация: 16.04.2015
Сообщений: 275
18.02.2019, 20:29 5
Нормально(для препода сойдёт).
0
213 / 160 / 52
Регистрация: 09.12.2017
Сообщений: 520
18.02.2019, 20:32  [ТС] 6
Цитата Сообщение от ReDoX Посмотреть сообщение
использовать нормальный генератор случайных чисел. rand() плохо справляется в зависимости от платформы с большими числами
спасибо за интересную статью.
Цитата Сообщение от ReDoX Посмотреть сообщение
можно заменить всю эту канитель на стандартную функцию shuffle
по условию, нужно написать свою функцию .
0
Эксперт C
25474 / 15861 / 3393
Регистрация: 24.12.2010
Сообщений: 34,718
18.02.2019, 21:09 7
JohnBlack123, вот тут есть много интересного
Генерация массива целых случайных чисел, которые не повторяются

Добавлено через 2 минуты
А еще обратите внимание на эту тему
Генератор случайных чисел без повторений
Там в посте 11 есть кое-что интересное.
1
213 / 160 / 52
Регистрация: 09.12.2017
Сообщений: 520
18.02.2019, 21:10  [ТС] 8
Байт, спасибо!
А как Вам моя реализация ?
Меня немного смущает мое условие проверки (b - a + 1) < length. Придумал второпях.
Верное ли оно или можно придумать лучше ?
0
Эксперт C
25474 / 15861 / 3393
Регистрация: 24.12.2010
Сообщений: 34,718
18.02.2019, 21:24 9
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
А как Вам моя реализация ?
Не очень. Она неправильна математически. При таких перестановках вы не получите равновероятные результаты. Это не вникая в детали реализации.
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
смущает мое условие проверки (b - a + 1) < length. Придумал второпях.
Тут все нормально. Если данное условие выполняется, то задача просто не имеет решения.
1
213 / 160 / 52
Регистрация: 09.12.2017
Сообщений: 520
18.02.2019, 21:43  [ТС] 10
Байт, спасибо. Сделал вот так, как Вы написали в ответах на другую тему :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void GenerateNonRepetitiveArray(int length, int *arr, int a, int b)
{
    for (int i = 0; i < length; i++)
        arr[i] = a+i;
 
    int random_index, temp;
    for (int k = length; k > 1; k--)
    {
        random_index = rand() % k;
 
        temp = arr[k - 1];
        arr[k - 1] = arr[random_index];
        arr[random_index] = temp;
    }
}
Но есть один вопрос. По сути, в эту функцию можно не передавать параметр диапазона b (функция с ним ничего не делает).
Может тогда сделать проверку на это условие : (b - a + 1) < length внутри функции, как считаете?
0
Эксперт C
25474 / 15861 / 3393
Регистрация: 24.12.2010
Сообщений: 34,718
18.02.2019, 22:17 11
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
есть один вопрос.
Штука в том, что предложенные там алгоритмы предполагают, что размер массива = длине интервала. А у вас это не обязательно. Выход такой. Сделать величину массива равной величине интервала.
arr = new int [b-a+1];
и уже заполнять этот массив.
Последние элементы (с индексами >= length) никому не нужны. И выводить ты должны до length. Но их присутствие в массиве необходимо для правильной работы алгоритма.

Добавлено через 6 минут
Конечно, если величина интервала здорово больше величины массива, тут возникают потери и в памяти, и во времени. И надо искать другой алгоритм. Там по 1-й ссылке Генерация массива целых случайных чисел, которые не повторяются есть вполне приличные алгоритмы. Кроме самого первого, основанного на случайных обменах (как у вас в первой попытке)
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.02.2019, 22:17

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Как заполнить одномерный массив случайными существенными числами в диапазоне?
ПОМОГИТЕ!!!

Заполнить одномерный динамический массив случайными числами в заданном диапазоне
как заполнить одномерный динамический массив случайными числами от -100 до +100 вот вариант от 1...

Заполнить массив случайными числами в диапазоне (6, 32), вывести в строку, упорядочить вставкой
Плиз очень сильно надо не знаю

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.