【问题标题】:How do I randomly display values within an array considering that each of these values has a unique corresponding value?考虑到每个值都有唯一的对应值,如何在数组中随机显示值?
【发布时间】:2011-11-07 05:33:54
【问题描述】:

使用 C,我如何在数组中随机显示值,考虑到这些值中的每一个都有一个唯一的对应值,而不重复显示这些值中的任何一个? 使用 C,我的目标是随机显示问题,一次一个,进行一定数量的迭代。我创建了一个包含问题及其四个可能答案的数组。我还创建了一个数组来保存每个问题的正确答案。

非常感谢...你们真的很有帮助

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h> 

int random();
int l, qs[10];
int main ()
{
for (l=0;l<10;++l)
qs[l]=0;
srand(time(NULL));
char questions [] [50]  ={"aa \n\na)\n\nb)\n\nc)\n\nd)",\"bb   \n\na)\n\nb)\n\nc)\n\nd)", "cc \n\na)\n\nb)\n\nc)\n\nd)", \
"dd \n\na)\n\nb)\n\nc)\n\nd)", "ee \n\na)\n\nb)\n\nc)\n\nd)", \
"ff \n\na)\n\nb)\n\nc)\n\nd)", "gg \n\na)\n\nb)\n\nc)\n\nd)", \
"hh \n\na)\n\nb)\n\nc)\n\nd)", "ii \n\na)\n\nb)\n\nc)\n\nd)", \
"jj \n\na)\n\nb)\n\nc)\n\nd)"};
char answers [10] = {'a','b', 'b','d','c','b','d','b' ,'c', 'b'};
int i, j;
char ans;
int score = 0;
printf ("Read each question carefully and choose your best answer.");
for (i=1;i<6;i++)
{
j = random();
fflush(stdin);
clrscr();
printf ("\n %d %s \n\n", i, questions [j]);
printf ("\n Enter Answer: ");
do
{
ans = tolower(getchar());
}while ( (ans < 'a') || (ans > 'd'));
printf ("\nYou chose: %c ", ans);
if (ans == answers[j])
{score = score + 1;
printf ("\n\nCorrect. %d Mark/s", score);
}else{printf ("\n\nIncorrect. 0 Mark/s");}
printf("\n\nPress Enter for next question...");
getch ();
}
getch ();
return 0;
}
random ()
{
int k;
do
{k=rand()%10;
}while (qs[k]!=0);
qs[k]= 1;
return k;
}

【问题讨论】:

  • 如果其中一个条件没有通过,则很好的无限 while 循环。

标签: c arrays loops random


【解决方案1】:

首先,我会改变您排列数据的方式。现在,您有三个并行数组,一个用于问题,一个用于潜在答案,一个用于正确答案。

取而代之的是,我会创建一个结构来保存单个问题的所有数据,如下所示:

struct qa { 
    char question[64];
    char answers[4][32];
    int correct_answer;
};

然后我会创建一个 qa 结构数组,每个结构包含一个问题和答案的所有数据:

qa questions[] = {
    { "what color is the sky?", { "red", "green", "blue", "yellow"}, 2},
    { "When is Christmas?", {"January", "July", "September", "December"}, 3},
    // ...
};

从那里,您有几个选择。如果您要问所有(或几乎)所有问题并且主要想重新排序,您可以按照@Salvatore Previti 的建议使用 Fisher-Yates shuffle。

如果您在任何给定时间只询问一小部分问题,那可能会非常浪费。在这种情况下,您可能会使用(例如)我在 previous answer 中讨论过的 Robert Floyd 发明的选择算法。

【讨论】:

    【解决方案2】:

    不要在 for 循环中调用 srand。在程序开始时调用它一次,然后让它继续。做你想做的最酷的方法是费舍尔-耶茨洗牌。如果您想使用它,您可以查找它。如果没有,这是简单的解决方案:

    1) 在循环之前,创建一个大小为 10 的 bool 数组(我称之为 usedArray)并将 all 设置为 false。

    2) 获取问题索引,获取0到9之间的随机数,包括(j = rand%10; 是好的),使得usedArray[j]为false;然后,将 usedArray[j] 设置为 true。您可能需要为此使用 while 或 do-while 循环。

    2) 你的问题现在是 questions[j],对应的答案是 answers[j]

    3) 必要时重复

    【讨论】:

      【解决方案3】:

      您需要另一个列表来跟踪您提取的项目。

      一个可能的解决方案:打乱输入数组。见http://benpfaff.org/writings/clc/shuffle.html

      如果您无法修改输入数组,则可以使用索引,这是一种间接级别。 这是另一种可能的解决方案。

      1) 你创建一个大小为 n 的整数数组。

      2) 用 0 到 n-1(包括在内)的值填充数组。

      3) 你对数组进行洗牌(寻找一种洗牌方法来随机化一个数组),例如再次http://benpfaff.org/writings/clc/shuffle.html

      4) 然后你在数组上从 0 迭代到 n-1(包括),数组中的每一项都将是源数组中的索引。

      完成。

      另一种可能的解决方案是使用链表。

      1) 你以随机顺序填充链表(这很容易)。

      以伪代码为例

      for (int i = 0; i < n; ++i)
      {
          if (rand() & 1)
              insert_at_the_beginning();
          else
              insert_at_the_end();
      }
      

      2) 当你需要一个新项目时,你从链表中弹出第一个项目。

      完成。

      你也可以保留一个布尔值数组,但是这种情况下算法的复杂度会更高,第一种方法似乎足够了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-09
        • 1970-01-01
        • 2022-07-21
        • 1970-01-01
        • 1970-01-01
        • 2020-10-17
        相关资源
        最近更新 更多