打印随机数以列出
Printing random numbers to list
我的任务是生成 50 到 80 范围内的随机数,如果生成的数字是偶数,则将其添加到偶数列表中,如果是奇数,则将其添加到奇数列表中。程序应该 运行 直到两个列表都填满 10 个数字。列表中不允许重复。此代码打印 20 个不同的数字,并将重复项存储在列表中。所以我认为问题出在 count_odd、count_even 和检查重复项上,但我找不到解决方案。此外,我还必须打印所有生成的数字以及最后的两个列表。链表中的数字应按降序排列
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
typedef struct list numbers;
typedef struct list* Pos;
int PrintRandom();
Pos CreateNew();
int PrintList(Pos);
struct list {
int number;
Pos next;
};
int PrintList(Pos P) {
if (P == NULL)
printf("Empty list.\n");
while (P != NULL) {
printf("%d\n", P->number);
P = P->next;
}
return 0;
}
Pos CreateNew() {
Pos q = NULL;
q = (Pos)malloc(sizeof(struct list));
if (q == NULL) return NULL;
q->next = NULL;
return q;
}
int PrintRandom() {
int x = 0, max = 80, min = 50;
x = (rand() % (max - min + 1) + min);
printf("Random number is : %d\n", x);
return x;
}
int main() {
srand(time(0));
Pos even, odd, q = NULL;
even = malloc(sizeof(numbers));
odd = malloc(sizeof(numbers));
even->next = odd->next = NULL;
int count_even = 0, count_odd = 0, j;
Pos head_p =even, head_n=odd;
while (count_even < 10 & count_odd < 10) {
j = PrintRandom();
if (j % 2 == 0) {
q = CreateNew();
if (q == NULL) return -1;
q->number = j;
while (even->next != NULL && even->next->number > q->number) {
even = even->next;
}
if (even->number== q->number)
free(q);
else
q->next = even->next;
even->next = q;
even =head_p;
count_even++;
}
else {
q = CreateNew();
if (q == NULL) return -1;
q->number = j;
while (odd->next != NULL && odd->next->number > q->number) {
odd = odd->next;
}
if (odd->number == q->number)
free(q);
else
q->next = odd->next;
odd->next = q;
odd = head_n;
count_odd++;
}
}
printf("Even numbers in list are:\n");
PrintList(head_p->next);
printf("Odd numbers in list are:n");
PrintList(head_n->next);
return 0;
}
您的代码有几个错误:
第一个错误:
循环
while (count_even < 10 & count_odd < 10) {
将在 count_even
或 count_odd
达到 10
时立即停止。但是,在您的问题中,您声明只有当两者都达到 10
.
时,循环才应该停止
因此,您应该将该行更改为以下内容:
while ( count_even < 10 || count_odd < 10 ) {
此外,值得指出的是 &
是按位与运算符。您可能打算使用逻辑与运算符,即 &&
.
第二个错误:
您在评论部分指出,如果其中一个列表已满(包含 10 个元素),则应丢弃属于该列表的所有其他数字。但是,您的程序不包含任何代码来检查这一点。相反,您的程序将继续向列表中添加新元素,即使它已经有 10 个元素。
第三个错误:
下面的代码是错误的:
if (even->number== q->number)
free(q);
else
q->next = even->next;
even->next = q;
even =head_p;
count_even++;
首先,你应该改变表达式
even->number== q->number
至:
even->next->number== q->number
但是,由于 even->next
可能为空,您必须事先对其进行测试,以便整行看起来像这样:
if ( even->next != NULL && even->next->number== q->number)
此外,行
even->next = q;
和
count_even++;
如果号码已经存在,则不应执行。因此,您应该将这些行移到 else
块内。执行这些更改后,您的代码应如下所示:
if ( even->next != NULL && even->next->number== q->number)
{
free(q);
}
else
{
q->next = even->next;
even->next = q;
count_even++;
}
even =head_p;
应该对奇数的代码分支执行相同的更改。
第四个错误:
下一行缺少一个反斜杠字符:
printf("Odd numbers in list are:n");
您应该将其更改为:
printf("Odd numbers in list are:\n");
补充说明:
我认为您的代码还有两点可以改进:
链表的第一个元素只是一个虚拟节点,其中number
字段没有被初始化。您似乎只是为了将头指针指向实际链表而使用此节点。
你有很多代码重复。您可以使用单独但非常相似的代码来处理每种情况,而不是使用相同的代码来处理偶数和奇数。
在下面的代码中,我重写了您的大部分代码,以向您展示我将如何解决这个问题。如果您觉得很难理解,请不要感到惊讶,因为我使用的是指向指针的指针,这对于初学者来说可能很难理解。如您所见,我没有使用任何虚拟节点,而且我还使用相同的代码来处理偶数和奇数。只有在我的代码的两个地方,我有不同的代码来处理偶数和奇数。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
struct list_node
{
int number;
struct list_node *next;
};
int PrintRandom();
int PrintList( struct list_node * );
int PrintList( struct list_node *p)
{
if ( p == NULL )
{
printf( "Empty list.\n" );
}
else
{
while ( p != NULL )
{
printf( "%d\n", p->number );
p = p->next;
}
}
return 0;
}
int PrintRandom() {
int x = 0, max = 80, min = 50;
x = (rand() % (max - min + 1) + min);
printf("Random number is : %d\n", x);
return x;
}
int main()
{
srand( (unsigned)time(NULL) );
struct list_node *head_even = NULL, *head_odd = NULL;
int count_even = 0, count_odd = 0, random;
bool is_even;
while ( count_even < 10 || count_odd < 10 )
{
struct list_node **pp, *p, *q;
//generate and print random number
random = PrintRandom();
//determine whether number is even or odd
is_even = random % 2 == 0;
//set pp to point to head pointer of the appropriate list
//and check whether the appropriate list is already full
if ( is_even )
{
if ( count_even >= 10 )
continue;
pp = &head_even;
}
else
{
if ( count_odd >= 10 )
continue;
pp = &head_odd;
}
for (;;) //infinite loop, equivalent to while (1)
{
p = *pp;
//if we reached the end of the list, break out of the loop
if ( p == NULL )
break;
if ( p->number <= random )
{
if ( p->number == random )
{
//discard number, because it already exists in list
//cannot use `continue` here, because that would go to
//the next iteration of the innermost loop, but we
//want to go to the next iteration of the outer loop
goto next_outer_loop_iteration;
}
else
{
break;
}
}
pp = &p->next;
}
//allocate memory for new node
q = malloc( sizeof *q );
if ( q == NULL)
{
fprintf( stderr, "error allocating memory for new node!\n" );
exit( EXIT_FAILURE );
}
//initialize new node
q->number = random;
q->next = p;
//insert node into list
*pp = q;
//increment the appropriate counter
if ( is_even )
count_even++;
else
count_odd++;
next_outer_loop_iteration:
continue;
}
printf("Even numbers in list are:\n");
PrintList( head_even );
printf("Odd numbers in list are:\n");
PrintList( head_odd );
//NOTE: The memory of the linked lists is not being freed
return 0;
}
我的任务是生成 50 到 80 范围内的随机数,如果生成的数字是偶数,则将其添加到偶数列表中,如果是奇数,则将其添加到奇数列表中。程序应该 运行 直到两个列表都填满 10 个数字。列表中不允许重复。此代码打印 20 个不同的数字,并将重复项存储在列表中。所以我认为问题出在 count_odd、count_even 和检查重复项上,但我找不到解决方案。此外,我还必须打印所有生成的数字以及最后的两个列表。链表中的数字应按降序排列
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
typedef struct list numbers;
typedef struct list* Pos;
int PrintRandom();
Pos CreateNew();
int PrintList(Pos);
struct list {
int number;
Pos next;
};
int PrintList(Pos P) {
if (P == NULL)
printf("Empty list.\n");
while (P != NULL) {
printf("%d\n", P->number);
P = P->next;
}
return 0;
}
Pos CreateNew() {
Pos q = NULL;
q = (Pos)malloc(sizeof(struct list));
if (q == NULL) return NULL;
q->next = NULL;
return q;
}
int PrintRandom() {
int x = 0, max = 80, min = 50;
x = (rand() % (max - min + 1) + min);
printf("Random number is : %d\n", x);
return x;
}
int main() {
srand(time(0));
Pos even, odd, q = NULL;
even = malloc(sizeof(numbers));
odd = malloc(sizeof(numbers));
even->next = odd->next = NULL;
int count_even = 0, count_odd = 0, j;
Pos head_p =even, head_n=odd;
while (count_even < 10 & count_odd < 10) {
j = PrintRandom();
if (j % 2 == 0) {
q = CreateNew();
if (q == NULL) return -1;
q->number = j;
while (even->next != NULL && even->next->number > q->number) {
even = even->next;
}
if (even->number== q->number)
free(q);
else
q->next = even->next;
even->next = q;
even =head_p;
count_even++;
}
else {
q = CreateNew();
if (q == NULL) return -1;
q->number = j;
while (odd->next != NULL && odd->next->number > q->number) {
odd = odd->next;
}
if (odd->number == q->number)
free(q);
else
q->next = odd->next;
odd->next = q;
odd = head_n;
count_odd++;
}
}
printf("Even numbers in list are:\n");
PrintList(head_p->next);
printf("Odd numbers in list are:n");
PrintList(head_n->next);
return 0;
}
您的代码有几个错误:
第一个错误:
循环
while (count_even < 10 & count_odd < 10) {
将在 count_even
或 count_odd
达到 10
时立即停止。但是,在您的问题中,您声明只有当两者都达到 10
.
因此,您应该将该行更改为以下内容:
while ( count_even < 10 || count_odd < 10 ) {
此外,值得指出的是 &
是按位与运算符。您可能打算使用逻辑与运算符,即 &&
.
第二个错误:
您在评论部分指出,如果其中一个列表已满(包含 10 个元素),则应丢弃属于该列表的所有其他数字。但是,您的程序不包含任何代码来检查这一点。相反,您的程序将继续向列表中添加新元素,即使它已经有 10 个元素。
第三个错误:
下面的代码是错误的:
if (even->number== q->number)
free(q);
else
q->next = even->next;
even->next = q;
even =head_p;
count_even++;
首先,你应该改变表达式
even->number== q->number
至:
even->next->number== q->number
但是,由于 even->next
可能为空,您必须事先对其进行测试,以便整行看起来像这样:
if ( even->next != NULL && even->next->number== q->number)
此外,行
even->next = q;
和
count_even++;
如果号码已经存在,则不应执行。因此,您应该将这些行移到 else
块内。执行这些更改后,您的代码应如下所示:
if ( even->next != NULL && even->next->number== q->number)
{
free(q);
}
else
{
q->next = even->next;
even->next = q;
count_even++;
}
even =head_p;
应该对奇数的代码分支执行相同的更改。
第四个错误:
下一行缺少一个反斜杠字符:
printf("Odd numbers in list are:n");
您应该将其更改为:
printf("Odd numbers in list are:\n");
补充说明:
我认为您的代码还有两点可以改进:
链表的第一个元素只是一个虚拟节点,其中
number
字段没有被初始化。您似乎只是为了将头指针指向实际链表而使用此节点。你有很多代码重复。您可以使用单独但非常相似的代码来处理每种情况,而不是使用相同的代码来处理偶数和奇数。
在下面的代码中,我重写了您的大部分代码,以向您展示我将如何解决这个问题。如果您觉得很难理解,请不要感到惊讶,因为我使用的是指向指针的指针,这对于初学者来说可能很难理解。如您所见,我没有使用任何虚拟节点,而且我还使用相同的代码来处理偶数和奇数。只有在我的代码的两个地方,我有不同的代码来处理偶数和奇数。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
struct list_node
{
int number;
struct list_node *next;
};
int PrintRandom();
int PrintList( struct list_node * );
int PrintList( struct list_node *p)
{
if ( p == NULL )
{
printf( "Empty list.\n" );
}
else
{
while ( p != NULL )
{
printf( "%d\n", p->number );
p = p->next;
}
}
return 0;
}
int PrintRandom() {
int x = 0, max = 80, min = 50;
x = (rand() % (max - min + 1) + min);
printf("Random number is : %d\n", x);
return x;
}
int main()
{
srand( (unsigned)time(NULL) );
struct list_node *head_even = NULL, *head_odd = NULL;
int count_even = 0, count_odd = 0, random;
bool is_even;
while ( count_even < 10 || count_odd < 10 )
{
struct list_node **pp, *p, *q;
//generate and print random number
random = PrintRandom();
//determine whether number is even or odd
is_even = random % 2 == 0;
//set pp to point to head pointer of the appropriate list
//and check whether the appropriate list is already full
if ( is_even )
{
if ( count_even >= 10 )
continue;
pp = &head_even;
}
else
{
if ( count_odd >= 10 )
continue;
pp = &head_odd;
}
for (;;) //infinite loop, equivalent to while (1)
{
p = *pp;
//if we reached the end of the list, break out of the loop
if ( p == NULL )
break;
if ( p->number <= random )
{
if ( p->number == random )
{
//discard number, because it already exists in list
//cannot use `continue` here, because that would go to
//the next iteration of the innermost loop, but we
//want to go to the next iteration of the outer loop
goto next_outer_loop_iteration;
}
else
{
break;
}
}
pp = &p->next;
}
//allocate memory for new node
q = malloc( sizeof *q );
if ( q == NULL)
{
fprintf( stderr, "error allocating memory for new node!\n" );
exit( EXIT_FAILURE );
}
//initialize new node
q->number = random;
q->next = p;
//insert node into list
*pp = q;
//increment the appropriate counter
if ( is_even )
count_even++;
else
count_odd++;
next_outer_loop_iteration:
continue;
}
printf("Even numbers in list are:\n");
PrintList( head_even );
printf("Odd numbers in list are:\n");
PrintList( head_odd );
//NOTE: The memory of the linked lists is not being freed
return 0;
}