Заполнение статического массива без повторяющихся чисел

#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 шт):

Автор решения: Falcon

Не сильно разбираюсь в с++. Немного поковырял этот код и скорее всего ошибка заключается при проверке 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;
    }


}
→ Ссылка
Автор решения: Harry

Ваш код не компилируется, но в принципе понятно, что вы хотели — при добавлении нового проверять имеющиеся элементы. Это можно сделать проще:

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

Хотя это и не самый эффективный способ...

→ Ссылка
Автор решения: Stanislav Volodarskiy

Случайный отбор десяти элементов из двадцати чисел - тасование Фишера-Йейтса:

#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
→ Ссылка