Наполнять array случайными числами ТАК, ЧТО числа не повторяться

у него было сомнение с прикладной программой в C. Я хочу наполнить array unidimensional (вектор) 15 элементов случайными числами, но не хочу, чтобы они повторились.

Произведенных чисел от 0 до 20 и использовал целую функцию existeElem, который возвращает 1, если элемент находится в векторе и 0 в противоположном случае. Проблема, - в чем я не знаю очень хорошо, как в том, чтобы применять эту функцию для того, чтобы случайные числа не повторились.

#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#define TAM 15
int  existeElem (int v[TAM], int longi, int num);
void generarVector (int v[TAM]);
void escribirVec (int v[TAM], int longi);

void main()
{
    int v[TAM], longi=TAM, num;

        generarVector(v);
        escribirVec(v, longi);

}

int existeElem(int v[TAM], int longi, int num)
{
    int i, enc=0;
    longi=TAM;

    for(i=0; i<longi && !enc; i++)
    {
        if(v[i]==num)
            enc=1;
    }

    return enc;
}

void generarVector (int v[TAM])
{
    int i, j, num, longi=TAM;
    srand((time)NULL);

    for (i=0; i<longi; i++)
    {
        v[i]=rand()%20+1;
        if(existeElem(v, longi, num))
            v[i]=     //no se muy bien como tratar con la funcion existeElem

    }

}

void escribirVec (int v[TAM], int longi)
{
    int i;
    longi=TAM;
    for(i=0; i<longi; i++)
        printf("%d ", v[i]);
}
3
задан 19.03.2016, 13:53
2 ответа

Сначала я скажу тебе, что делая rand()%20+1 ты получаешь числа 1 в 20 и не от 0 до 20 (которые являются 21 различным числом). Чтобы получать числа 0-20 ты был бы должен делать rand()%21.

Секунда, способ призывать srand у него есть ошибка: ты не должен делать srand((time)NULL);, правильная форма srand(time(NULL));, так как ты хочешь призвать в функцию time и то, что ты делаешь, castear NULL в тип time, и сделав это, всегда ты даешь ему то же зерно генератору случайных чисел, что ты не хочешь, так как они будут менее случайными.

Потом, чтобы находить случайное число, которое не существовало бы в твоей договоренности, ты можешь делать его один while(existeElem(v, longi, num = rand()%21));

Объяснение:

  • while: в то время как
    • existeElem: существует элемент в array
    • num = rand()%21: устанавливать num со случайной стоимостью между 0 и 20

Здесь num у него есть 2 списка, сначала он проходит как результат для existeElem и секунда остается установленной, чтобы потом быть использованным в ассигновании v[i].

Измененная функция:

void generarVector (int v[TAM])
{
    int i, j, num, longi=TAM;
    srand(time(NULL));

    for (i=0; i<longi; i++)
    {
        while(existeElem(v, longi, num = rand()%21));
        v[i]= num;
    }

}
3
ответ дан 24.11.2019, 14:42
  • 1
    Осталось все очень ясным. Большое спасибо: D – DDN 19.03.2016, 17:22

У твоего решения есть проблема, что, как каждый раз, когда случайное число тебе не нравится, ты вновь ищешь случайный другой, ты подвергаешься риску того, чтобы находить всегда числа, которые тебе не нравятся, возможности оставаться "подвешенным" - мало, но если уже у тебя есть 14 чисел, для 15 только они будут стоить тебе 7 из 21 возможного, и все разы, которые он повторит до того, чтобы находить один, который стоил бы, это потерянное время. Предельный пример, ты хочешь искать 1.000.000 случайных чисел 0 в 999.999, не повторяясь, в последнем числе всех, если только лишенная, из-за того, что '5' выходить например, ты будешь выбирать числа random от 0 до 999.999 до тех пор, пока он не получится 5, не, объясняюсь ли я... Изящество темы состоит в том, чтобы он сделал это первой.

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

Я сделал пример, это не функция, одинокий образец, которое я имею в виду:

#include <iostream>
#include <stdlib.h>
#include<time.h>
int main(void){
    int lista[15];      // lista de 15 numeros aleatorios de 0 a 20 sin repetirse
    bool elegidos[21]; // ¿ya salio ese numero? (del 0 al 20)
    int posibles=21;
    int contador,posicion;
    int i,j;
    srand(time(NULL));

    for (i=0; i<21; i++) elegidos[i]=false; // Empieza que no se ha elegido ningun numero
    for (i=0; i<15; i++) {
        posicion=rand()%posibles+1;  // elige al azar una posicion entre los no elegidos (de 1 a 21)
        j=0;
        contador=0; // cuenta los numeros no elegidos que encuenta.
        while (contador<posicion) {         // Cuenta las posiciones no elegidas
            if (!elegidos[j++])contador++;  // Si el numero ya fue elegido se ignora
        }
        j--; // Cuando encuentra la posicion hace un j++ de mas.
        elegidos[j]=true;   // se marca la posicion como elegida
        posibles--;         // hay una posicion "no elegida" menos
        lista[i]=j;         // La posicion dentro la lista de elegidos es el numero a guardar
        std::cout << "lista["<<i<<"]= "<< j << "\n";
    }
}
1
ответ дан 24.11.2019, 14:42