[英]Randomizing nodes in linked list, C program
the following function is part of sort of a game with questions and answers. 以下功能是带有问题和答案的游戏的一部分。 I have a problem with the randomization of the questions by their complexity-some questions appear more than once and the first also appears in every level, which should not happen.
我对问题的随机性有一个问题,那就是它们的复杂性-有些问题不止一次出现,而且第一个问题也出现在每个级别,这是不应该发生的。 Please help!
请帮忙!
typedef struct
{
char question[300];
char date[30], author[30], ansr1[80], ansr2[80], ansr3[80], ansr4[80];
int id, correctAnsr, level;
} game;
typedef struct Node
{
game data;
struct Node* next;
} node;
void printRandom1(node *head)
{
if (isEmpty(head))
return;
srand(time(NULL));
node *result = head->data.question;
node *current = head;
int n;
for (n = 17; current != NULL; n++)
{
if (rand() % n == 0 && current->data.level == 0)
result = current->data.question;
current = current->next;
}
printf("%s\n", result);
int i, ans;
printf("1.-%s\n", result->data.ansr1);
printf("2.-%s\n", result->data.ansr2);
printf("3.-%s\n", result->data.ansr3);
printf("4.-%s\n", result->data.ansr4);
printf("Enter the correct answer: ");
scanf("%d", &ans);
if (ans == result->data.correctAnsr)
printf("CORRECT ANSWER!\n");
else
{
printf("WRONG ANSWER\n");
printf("GAME OVER");
printf("The correct answer is: %d\n", result->data.correctAnsr);
return menu();
exit(1);
}
}
Ad " some questions appear more than once ": this is because you do not track used questions anyhow -- your random choice method always selects from the list of all questions (regardless if they have already been asked or not). 广告“ 一些问题出现不止一次 ”:这是因为您无论如何都不会跟踪使用过的问题-您的随机选择方法总是从所有问题的列表中进行选择(无论是否已经提出问题)。
Ad " first also appears in every level ": my bet is that your random choice method (which is quite strange) is not guaranteed to select a question (ie the result = current->data.question
part may not be executed with quite high probability). 广告“ 首先也出现在每个级别 ”:我敢打赌,您的随机选择方法(很奇怪)不能保证选择一个问题(即
result = current->data.question
部分可能执行得不是很高)可能性)。 The initial value of result
is kept in this case (which happens to be the first question). 在这种情况下,
result
的初始值将保留(恰好是第一个问题)。
Below is a modified version of your code. 下面是代码的修改版本。 Some remarks:
一些说明:
counting the number of questions in linked list is added. 计算链接列表中的问题数量。 It is needed for the random choice which selects among the answers with equal probability (to be correct -- there is some negligible bias, but probably not important here)
需要以相等的概率从答案中进行选择的随机选择(正确的做法是-可以忽略不计,但在这里可能并不重要)
used answers are tracked in a new linked-list 在新的链接列表中跟踪使用的答案
there is no level logic implemented. 没有实现级别逻辑。 You may want to remove questions with inappropriate level from the linked list at the beginning of the game
您可能想在游戏开始时从链接列表中删除不适当级别的问题。
the current
variable is a pointer-to-a-pointer which simplifies the unlinking process (you do not need to keep the previous entry pointer this way) current
变量是一个指向指针的指针,它简化了取消链接的过程(您无需以这种方式保留先前的入口指针)
Code: 码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct
{
char question[300];
char date[30], author[30], ansr1[80], ansr2[80], ansr3[80], ansr4[80];
int id, correctAnsr, level;
} question;
typedef struct questionListNode {
question data;
struct questionListNode* next;
} questionListNode;
typedef struct {
questionListNode* headAvailable; // Your former head variable
questionListNode* headUsed; // Initialize this to NULL
int numberOfAvailableNodes; // Number of nodes in headAvailable
int numberOfCorrectAnswers; // Number of nodes in headUsed
} game;
void printRandom1(game* currentGame)
{
if (currentGame->headAvailable == NULL || currentGame->numberOfAvailableNodes <= 0) {
printf("No more questions, you've won!\n");
exit(1);
}
srand(time(NULL)); // Consider moving this to the start of main()
int chosenIndex = rand() % currentGame->numberOfAvailableNodes;
questionListNode** current = &(currentGame->headAvailable);
while ((chosenIndex > 0) && (*current != NULL)) { // the second check is for safety
current = &((*current)->next);
chosenIndex--;
}
questionListNode* currentQuestion = (*current);
if (currentQuestion == NULL) {
printf("Internal error: available count mismatch!\n");
exit(1);
}
printf("%s\n", currentQuestion->data.question);
int i, ans;
printf("1.-%s\n", currentQuestion->data.ansr1);
printf("2.-%s\n", currentQuestion->data.ansr2);
printf("3.-%s\n", currentQuestion->data.ansr3);
printf("4.-%s\n", currentQuestion->data.ansr4);
printf("Enter the correct answer: ");
scanf("%d", &ans);
if (ans != currentQuestion->data.correctAnsr) {
printf("WRONG ANSWER\n");
printf("GAME OVER\n");
printf("The correct answer is: %d\n", currentQuestion->data.correctAnsr);
exit(1);
}
printf("CORRECT ANSWER!\n");
// Remove currentQuestion from the available list
(*current) = currentQuestion->next;
// Put currentQuestion into used list
currentQuestion->next = currentGame->headUsed;
currentGame->headUsed = currentQuestion;
// Update counters
currentGame->numberOfAvailableNodes--;
currentGame->numberOfCorrectAnswers++;
}
int main(int c, char** t)
{
game g;
g.headAvailable = NULL;
g.headUsed = NULL;
g.numberOfAvailableNodes = 0;
g.numberOfCorrectAnswers = 0;
questionListNode q1 = { { "Question 1", "", "", "A1*", "B1", "C1", "D1", 1, 1, 0 }, NULL };
questionListNode q2 = { { "Question 2", "", "", "A2", "B2*", "C2", "D2", 2, 2, 0 }, &q1 };
questionListNode q3 = { { "Question 3", "", "", "A3", "B3*", "C3", "D3", 3, 2, 0 }, &q2 };
g.headAvailable = &q3;
g.numberOfAvailableNodes = 3;
while (1)
printRandom1(&g);
}
Some additional (random) notes: 其他一些(随机)注意事项:
I am not sure linked-list is the best data structure for this task 我不确定链表是否是此任务的最佳数据结构
Consider naming your typedefs with some prefix (eg t_game
, t_node
) 考虑使用一些前缀来命名您的typedef(例如
t_game
, t_node
)
If you wanted to re-start the game (instead of exit()
) you would need to join the two linked lists back together and reset the counters 如果您想重新开始游戏(而不是
exit()
),则需要将两个链接列表重新连接在一起并重置计数器
Good luck! 祝好运!
Disclaimer: I did not spend that much time checking the code so please take it just as an example... 免责声明:我没有花太多时间检查代码,因此请仅以它为例...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.