Заполнение статического массива без повторяющихся чисел
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
/* Написать программу которая заполняет массив 10 элементов диапазон значений
случайных чисел 20, и в массиве не должно быть одинаковых значений!*/
void main()
{
setlocale(LC_ALL, "ru");
srand(time(NULL));
int const macciv = 10;
int arr[macciv]{};
int end = 0;
int j = 0;
for (int i = 0; i < macciv; i++)
{
arr[i] = rand() % 20;
}
while (true)
{
if (j == end)
{
end++;
}
else
{
if (arr[j] != arr[end])
{
end++;
if (end == 9)
{
end = 0;
j++;
}
}
else
{
arr[end] = rand() % 20;
j = 0;
end = 1;
}
}
if (j == 9)
{
break;
}
}
for (int k = 0; k < macciv; k++)
{
cout << arr[k] << endl;
}
}
Написал программку для решения задачи для заполнения массива не повторяющимися числами, тк знаю только о условиях, циклах, статических массивах, rand, функции continue и break и всё по сути, только недавно начал изучать c++ и при компиляции пишет завершил работу с кодом -1073741819, не понимаю в чём проблема, цикл там очень долгий, но не должен быть бесконечным, ведь рано или поздно он же создаст массив что мне нужен?.. ошибка говорит об обращении в памяти к несуществующему или удаленному элементу, но когда компьютер обращается к этому самому элементу и почему он к нему обращается и что это за элемент, ведь на сколько я понимаю цикл просто постоянно перезаписывает массив когда находит совпадение, массив один и тот же, до цикла с выводом программа не доходит.
Ответы (3 шт):
Не сильно разбираюсь в с++. Немного поковырял этот код и скорее всего ошибка заключается при проверке if (j == end), значение end увеличивается, а j не обновляется и как итог пропуск индексов массива, вот и выбивает ошибку. Можно несколько упростить код и избавиться от такого количества конструкций if, скажем так, переписать проверку на дублирование. Например:
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace std;
void main()
{
srand(time(NULL));
const int macciv = 10;
int arr[macciv]{};
int i = 0;
while (i < macciv)
{
int randomNumber;
do
{
randomNumber = rand() % 20;
// Проверка наличия дубликата
bool isDuplicate = false;
for (int j = 0; j < i; j++)
{
if (arr[j] == randomNumber)
{
isDuplicate = true;
break;
}
}
if (!isDuplicate)
break;
} while (true);
arr[i] = randomNumber;
i++;
}
for (int k = 0; k < macciv; k++)
{
cout << arr[k] << endl;
}
}
Ваш код не компилируется, но в принципе понятно, что вы хотели — при добавлении нового проверять имеющиеся элементы. Это можно сделать проще:
int main()
{
srand(time(NULL));
int const macciv = 10;
int arr[macciv]{};
for(int i = 0; i < macciv; ++i)
{
bool uniq = true;
do {
uniq = true;
arr[i] = rand() % 20;
for(int j = 0; j < i; ++j)
if (arr[i] == arr[j]) { uniq = false; break; }
} while(!uniq);
}
for (int k = 0; k < macciv; k++)
{
cout << arr[k] << " ";
}
cout << endl;
}
Хотя это и не самый эффективный способ...
Случайный отбор десяти элементов из двадцати чисел - тасование Фишера-Йейтса:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define R 20
#define N 10
int main()
{
srand((unsigned)time(NULL));
// заполнение последовательными числами
int a[R];
for (int i = 0; i < R; ++i)
{
a[i] = i;
}
// отбор случайного подмножества
for (int i = 0; i < N; ++i)
{
int j = i + rand() % (R - i); // случайный j: i <= j < R
int temp = a[i]; // поменять местами a[i], a[j]
a[i] = a[j];
a[j] = temp;
}
// печать
for (int i = 0; i < N; ++i)
{
printf(" %d", a[i]);
}
printf("\n");
}
$ gcc temp.c $ ./a.out 7 9 3 18 6 19 14 13 8 2 $ ./a.out 11 3 7 14 16 15 18 5 4 9 $ ./a.out 18 14 9 12 16 6 3 15 2 11