Lilyanaa Ответов: 2

Генерация случайных чисел в C


Привет,у меня есть два меню [menu1, menu2] Я хочу выбрать разные имена для этих двух меню в соответствии с генерируемым случайным числом(либо 1, либо 2), поэтому я использовал menu1[r1].c1[r1] и menu2[r2].c2[r2], чтобы проверить, равно ли оно нулю, в этом случае я выбираю форму имени menu1[r1].n1[r1] и menu2[r2].n2[r2].
Так что если все элемент menu1[Р1].С1[Р1] =1 ,то программа должна генерировать различные случайные числа, выход должен быть mee1,mee2,me16,mee4,mee5,me13,mee7,mee8,mee9,почтовый индекс me10,me11,ме12,mee6,me14,me15,mee3

или по-разному расположить в соответствии со случайным числом, которое генерирует

Что я уже пробовал:

---

phil.o

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

Lilyanaa

спасибо за ваши усилия, на самом деле я не знаю, почему условия if не работают, я просто хочу, чтобы вывод состоял из 16 имен, по восемь из каждого меню и без дубликатов в именах

phil.o

Хорошо, я вижу; на самом деле вам не нужно, чтобы переменные-члены в ваших структурах были массивами (за исключением имен, которые являются массивами символов, bt я покажу вам, как их объявлять). И вы используете переменную-член c, чтобы узнать, было ли заданное имя уже атрибутировано, не так ли?
Проблема в том, что из 16 случайных чисел 1 или 2 ничто не гарантирует, что вы получите 8 единиц и 8 двоек; у вас может быть 10 единиц и 6 двоек или 5 единиц и 11 двоек.

phil.o

Так что позвольте мне перефразировать, чтобы быть уверенным, что я понял:
вы хотите, чтобы в вашем конечном результате был получен массив из 16 f структур, каждая из которых имеет случайное распределение имен "mee1", "mee2",..., "me16", причем каждое имя является уникальным и исходит из массива menu1 или menu2 в зависимости от случайного числа?

Lilyanaa

Да, поэтому я использую if(count1<=8), чтобы гарантировать, что не выберет больше 8, Если новое случайное число тоже будет 1, оно должно генерировать новое случайное число и в то же время .c1 будет all = 1, потому что все 8 имен были выбраны

phil.o

Я понимаю, но ты не можешь так поступить. Я готовлю второй ответ, который представит вам альтернативу.

Lilyanaa

большое вам спасибо, я жду

2 Ответов

Рейтинг:
2

phil.o

Чтобы сгенерировать случайное число 1 или 2, Вы можете использовать следующий код:

#include <stdlib.h>

int random_number = (rand() % 2) + 1;


Надеюсь, это поможет.


Lilyanaa

это то же самое, r = rand() % (2 + 1 - 1) + 1 ;

phil.o

Да, это так. Но в этом случае получается именно случайное число, которое равно либо 1, либо 2.
Поэтому, если это не то, что вы хотите, пожалуйста, попробуйте перефразировать Ваше требование.

Lilyanaa

Мне объяснили, что я хочу в своем вопросе, не могли бы вы помочь, пожалуйста?

phil.o

Нет, потому что я старался изо всех сил, но не могу понять вашего требования.
Вот почему я прошу вас перефразировать его, потому что сейчас я совершенно не смогу вам помочь.
Как только я пойму, что тебе нужно, все пойдет гораздо быстрее.

Lilyanaa

Хорошо, я постараюсь, спасибо

raddevus

Я просто скомпилировал его и запустил примерно 10 раз, и каждый раз получал 2.
Я поместил программу в сценарий оболочки и вызвал ее несколько раз, и все равно каждый раз получал 2.
Нужно ли сначала засеять вызов rand() или что-то в этом роде?
Просто любопытно

Вот мой код
#include <stdlib.h>
#include <iostream>
использование пространства имен std;
тап_п(){
int random_number = (rand() % 2) + 1;
соиь <&ЛТ; random_number на <<епси;
}

РЕДАКТИРОВАТЬ
Я добавил следующую строку кода перед вызовом rand (), и теперь она, похоже, генерирует 1 в качестве выходного сигнала.
srand(time(NULL));

phil.o

Странно, потому что я сделал то же самое в VS и вот что я получил:

#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
   for (int i = 0; i < 50; ++i) cout << (rand() % 2) + 1 << ' ';
   cout << '\n';
   system("pause");
}

Результат:
2 2 1 1 2 1 1 1 1 1 2 2 2 2 2 2 2 1 2 1 2 1 1 2 1 1 2 1 1 2 2 1 2 1 2 1 2 2 2 1 2 2 1 2 2 1 2 2 2 1
Press a key...

raddevus

Это интересно и может быть потому, что моя программа работает несколько раз-это означает, что случайное значение высевается одинаково каждый раз, когда оно запускается. Я добавлю петлю к своей, просто чтобы посмотреть, что она делает.

Мой также скомпилирован с g++ под Debian, но поскольку это все стандартные библиотечные материалы, это не должно иметь значения.

РЕДАКТИРОВАТЬ
Да, именно так. Я добавил цикл for для вызова rand() десять раз, и я получаю псевдослучайный список значений.
2 1 2 2 2 2 1 1 2 2
Однако каждый раз, когда я запускаю его, я получаю тот же самый список из 10 значений, конечно.

И, конечно, если я добавлю вызов srand (), то каждый раз, когда я запускаю программу, я получаю более случайный список из 10 значений.

Вот мой последний код:

#include <stdlib.h>
#include <iostream>
использование пространства имен std;
тап_п(){
srand(time(NULL));
int random_number = (rand() % 2) + 1;
for (int i = 0; i< 10;i++){
cout << random_number << " " ;
random_number = (rand()%2)+1;
}
cout << endl;

}

k5054

Вам нужно заполнить генератор случайных чисел, иначе вы всегда получите одну и ту же последовательность. Это делается путем вызова функции srand(). Я часто использую srand(time(0)), то есть заполняю генератор случайных чисел текущим временем в секундах. Это работает под linux и, вероятно, mac-os тоже. Windows может делать все по-другому.

Рейтинг:
2

phil.o

Я думаю, что почти понял, что вы хотите сделать, но я думаю, что вы не можете сделать это так, как вы закодировали (см. Мой комментарий).
Проблема в том, что если вы возьмете случайное число (1 или 2) 16 раз, ничто не гарантирует, что у вас будет одинаковое количество единиц и двоек. Даже установив флаг в поле c переменная-член, как вы это сделали, полностью портит алгоритм. Я думаю, что иметь массив из 16 имен, которые вы бы перетасовали, было бы намного чище.
Вы могли бы сделать это так:

#include <time.h>

struct f
{
   const char* name;
};

// Shuffles an array
void shuffle(f menu[], size_t count);

// The size of the array
const int SIZE = 16;

int main() {
   // Declarations
   int i;
   struct f menu[SIZE];

   // Initializations
   menu[ 0].name = "mee1";
   menu[ 1].name = "mee2";
   menu[ 2].name = "mee3";
   menu[ 3].name = "mee4";
   menu[ 4].name = "mee5";
   menu[ 5].name = "mee6";
   menu[ 6].name = "mee7";
   menu[ 7].name = "mee8";
   menu[ 8].name = "mee9";
   menu[ 9].name = "me10";
   menu[10].name = "me11";
   menu[11].name = "me12";
   menu[12].name = "me13";
   menu[13].name = "me14";
   menu[14].name = "me15";
   menu[15].name = "me16";

   // Shuffle the numbers
   shuffle(menu, SIZE);
}

// Algorithm from https://benpfaff.org/writings/clc/shuffle.html
void shuffle(f menu[], size_t count) {
   size_t i, j;
   f t;
   srand((unsigned int)time(NULL));
   if (count > 1) {
      for (i = 0; i < count - 1; ++i) {
         j = i + rand() / (RAND_MAX / (count - i) + 1);
         t = menu[j];
         menu[j] = menu[i];
         menu[i] = t;
      }
   }
}

Я сильно изменил ваш первоначальный алгоритм, но это потому, что я не думаю, что вы могли бы достичь этого так, как вы это сделали. Я сохранил его. f структура, но избавился от нее str1 и str2 так как они только привнесли некоторые ненужные сложности.
Я знаю, что это большое изменение, и не зная точного требования, это может быть неправильным решением. Если это не так, мои извинения. Я не думаю, что смог бы только слегка изменить Ваше решение и достичь того же результата.

Как я уже сказал, У меня нет компилятора языка Си. Я протестировал его на проекте VS 2017 C++ , и я действительно получаю ожидаемое перетасование имен.


Lilyanaa

Нет, я должен использовать два меню, логически мой код должен быть правильным, если .c1 больше 8, должен генерировать новое случайное число, но я не знаю, почему это не работает, в любом случае большое вам спасибо