Генерация случайного массива в C

Я разрабатываю на C с использованием OpenVMS, я сделал код, который помещает массив из 1001 (0-1000) элементов, 1000 (0-999) случайных чисел от 0 до 50. Вот код:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

main(){
    int vet[1000], fre[50];
    int i;

    srand(time(NULL));

    for(i=0;i<1000;i++){
        vet[i]=(rand()%51);
    }

    for(i=0;i<1000;i++){
        printf("%d\n", vet[i]);
    }

    for(i=0;i<1000;i++){
        fre[vet[i]]=fre[vet[i]]+1;
    }

    for(i=0;i<51;i++){
        printf("The number %d  was generated %d times\n", i, fre[i]);
    }
}

Когда я показываю, сколько раз было сгенерировано каждое число, я увидел, что число 50 имеет большое число, иногда более чем в два раза больше, чем другие числа, кто-нибудь может мне помочь?

РЕШЕНО Код, который работает Сейчас я должен использовать srand()

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

main(){
        int vet[1000], fre[51] = {0};
        int i;

        srand(time(NULL));

        for(i=0;i<1000;i++){
                vet[i]=(rand()%51);
        }

for(i=0;i<1000;i++){
printf("%d\n", vet[i]);
}

        for(i=0;i<1000;i++){
                        fre[vet[i]]=fre[vet[i]]+1;
        }

        for(i=0;i<51;i++){
                printf("The number %d  was generated %d times\n", i, fre[i]);
        }
}
[EOB]

Спасибо всем


person Mitro    schedule 10.12.2012    source источник
comment
rand() PRNG очень низкого качества. Если вы d требуют высококачественного потока PRN. Если GSL компилируется на OpenVMS, он поставляется со многими PRNG. В крайнем случае OpenVMS поддерживает drand48 PRNG. На боковом узле fre никогда не инициализируется (все 0).   -  person Hristo Iliev    schedule 10.12.2012
comment
Я никогда не использовал эти другие, я буду смотреть их сегодня вечером, спасибо! ;)   -  person Mitro    schedule 10.12.2012


Ответы (3)


    int vet[1000], fre[50];


    for(i=0;i<51;i++){
            printf("The number %d  was generated %d times\n", i, fre[i]);
    }

Проблема 1: Вы объявляете fre состоящим из 50 элементов, но используете 51.

Проблема 2: fre не инициализирован.

int vet[1000], fre[51] = {0};

должен дать вам разумный результат.

person Daniel Fischer    schedule 10.12.2012
comment
Почему 51? Массив не начинается с 0? поэтому, когда я пишу массив [50], это 0,1,2,...,49,50?? итого 51, я не понимаю, если я напишу 51 я смогу поместить в массив 52 элемента, я ошибаюсь? - person Mitro; 10.12.2012
comment
Нет, type array[N]; объявляет массив из N элементов типа type. Допустимые индексы от 0 до N-1. Таким образом, int fre[50]; дает вам индексы от 0 до 49. Чтобы использовать индекс 50, вам нужен 51 элемент. - person Daniel Fischer; 10.12.2012
comment
Ок спасибо теперь работает!! Почему мне показали такое большое число в 50? Что случилось? - person Mitro; 10.12.2012
comment
@AlessioMTX Многое могло случиться. Чтение/запись за пределами массива - это поведение undefined, поэтому то, что на самом деле произошло, зависит от реализации, параметров компилятора, .... Возможно, вы просто записали и прочитали неиспользуемый слот памяти, содержащий мусор, или защиту стека, или адрес возврата, я не знаю. - person Daniel Fischer; 10.12.2012
comment
@Joze На самом деле, лучше, если код будет ошибаться при неопределенном поведении, IMO. Если это так, это четкое сообщение, если нет, вы можете вообще не заметить, что что-то не так. - person Daniel Fischer; 10.12.2012
comment
Я явно пошутил! Я абсолютно согласен ! - person Joze; 10.12.2012
comment
Segfault — это тип ошибки, которую вы получили по разным причинам, например, из-за нарушения прав доступа. В вашем случае у вас была огромная вероятность получить эту ошибку. Когда вы получите эту ошибку, ваша программа полностью выйдет из строя! Подробнее об этом читайте здесь: en.wikipedia.org/wiki/Segmentation_fault Каждый программист на C сталкивался с эта ошибка, по крайней мере, один раз! :) - person Joze; 10.12.2012
comment
О да, это случилось со мной XD, но я не знал, что это его имя! - person Mitro; 10.12.2012

int vet[1000], fre[50];

В вашем массиве vet[] 1000 записей, а не 1001. В fre[] 50, а не 51. Если вы генерируете числа от 0 до 50, вам нужно объявить fre[] как fre[51];

Вы также никогда не очищаете массив fre[] перед накоплением результатов.

person JasonD    schedule 10.12.2012
comment
Массив не начинается с 0? поэтому, когда я пишу массив [50], это 0,1,2,...,49,50?? всего 51, я не понимаю - person Mitro; 10.12.2012
comment
Массивы начинаются с нуля, но число — это количество элементов, а не максимальный индекс. Итак, fre[50] дает fre[0].. fre[49] - person JasonD; 10.12.2012
comment
Индексируя конец вашего массива, вы получали доступ к памяти, используемой чем-то другим, с непредсказуемыми результатами. - person JasonD; 10.12.2012

1) Инициализируйте свои переменные перед их использованием:

int vet[1000] = {0};
int fre[50] = {0};

2) Вы проверяете значения за пределами размера массива:

for(i=0;i<51;i++){  

должно быть:

for(i=0;i<50;i++){

Ваш массив fre[50] содержит элементы с fre[0] по fre[49]. Итак, вы хотите, чтобы ваш счет начинался с 0 и переходил к <50, то есть к 49.

3) Вы генерируете числа за пределами размера вашего массива:

vet[i]=(rand()%51);

должно быть:

vet[i]=(rand()%50); 

rand() % x сгенерирует число между 0-(x-1), если ваш массив имеет размер 50, то его элементы будут 0-49, что означает, что вам нужно выбрать %50, иначе вы превысите размер массива при назначении: fre[vet[i]]=fre[vet[i]]+1;

4) Имейте в виду, что функция rand() генерирует псевдослучайный вывод, поэтому всегда шанс, что это не будет таким "случайным", как вы хотели.


EDIT
Хорошо, ваш комментарий: 2) No because I'm checking also 0 заставляет меня думать, что вы не понимаете, как работают массивы:

int fre[50] = {0};

дает вам массив из 50 элементов. Индекс массивов начинается с 0 и переходит к [количество элементов - 1], так что:

first element -->fre[0], fre[1], fre[2], ..., fre[48], fre[49] <-- last element

Если вы хотите записать значения от 0 до 50 включительно, вам потребуется 51 элемент в массиве:

int fre[51] = {0};

Итак, оба из них:

for(int i=0; i<50; i++)    and    for(int i=0; i<51; i++)

начните с 0 и пройдитесь по каждому элементу, но первый работает с fre[50] (пятьдесят элементов от 0 до 49), а второй работает с fre[51] (пятьдесят один элемент, от 0 до 50)

person Mike    schedule 10.12.2012
comment
3) Если я делаю% 50, у меня есть число от 0 до 49 - person Mitro; 10.12.2012
comment
2) Нет, потому что я тоже проверяю 0 - person Mitro; 10.12.2012
comment
@AlessioMTX - да, вы должны сделать это, чтобы не переполнить свой массив fre[50]. Если вы хотите делать числа от 0 до 50, вы должны увеличить размер fre на 1. - person Mike; 10.12.2012
comment
Я сделал int fre[51], как мне сказали Даниэль и Джейсон. И теперь работает. У меня нет переполнения. - person Mitro; 10.12.2012
comment
37 20 25 24 40 36 0 50 49 27 23 Это некоторые числа и в 1000 элементов у меня мин 0 макс 50 - person Mitro; 10.12.2012
comment
Нет, я понимаю, как работает массив, если я поставлю 50 вместо 51, прогон будет показывать мне, пока число 49 не будет сгенерировано X раз. - person Mitro; 10.12.2012