鱼C论坛

 找回密码
 立即注册
查看: 366|回复: 2

[C\C++] 麻烦看看这个为啥会无限循环

[复制链接]
发表于 2024-4-22 17:41:32 | 显示全部楼层 |阅读模式
20鱼币
用C语言实现的舞伴配对问题,为什么会无限循环?
#include<stdio.h>
#include<stdlib.h>
#define size 50
typedef struct
{
        char name[20];
        char male;
}people;
typedef struct
{
        people* ren;
        int front,rear;
}S;
void init(S* st)
{
        st->ren=(people *)malloc(size*sizeof(people));
        st->front=st->rear=0;//初始化顺序栈
}
int full(S* st)//判断队列是否满
{
        if(((st->rear)+1)%size==st->front)
                return 1;
        return -1;
}
int empty(S* st)//判断队列是否为空
{
        if(st->rear==st->front)
                return -1;
        else return 1;
}
int enter(S* st,people person)//插入元素
{
        if(full(st))
        {
                printf("队列已满\n");
                return 1;
        }
        st->ren[st->rear]=person;
        st->rear=(st->rear+1)%size;
        return -1;
}
int pop(S* st,people* person)
{
        if(!empty(st))
        {
                printf("空\n");
                return -1;
        }
        *person=st->ren[st->front];
        st->front=(st->front+1)%size;
        return 1;
}
people gethead(S Q)
{//返回Q的队头元素,不修改队头指针
        if(Q.front!=Q.rear) //队列非空
                return Q.ren[Q.front]; //返回队头元素的值,队头指针不变
}
void dance(people dancers[],int n)
{
        S man,woman;
        people person;
        init(&man);
        init(&woman);
        int i;
        for(i=0;i<n;i++)
        {
                if(dancers[i].male=='F')
                {
                        enter(&woman,dancers[i]);
                }
                if(dancers[i].male=='M')
                {
                        enter(&man,dancers[i]);
                }
                else
                        printf("性别输入错误:%s %c\n",dancers[i].name,dancers[i].male);
        }
        printf("舞伴配对如下\n");
        while(empty(&man)&&empty(&woman))
        {
                pop(&woman,&person);
                printf("%s女士与",person.name);
                pop(&man,&person);
                printf("%s男士配对\n",person.name);
        }
        if(empty(&man))
        {
                person=gethead(man);
                printf("%s男士将在下一轮第一个获得匹配机会\n",person.name);
        }
        if(empty(&woman))
        {
                person=gethead(woman);
                printf("%s女士将在下一轮第一个获得匹配机会\n",person.name);
        }

}
int main()
{
        int n,i;
        people wuzhe[size];
        printf("请输入等待的总人数\n");
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
                printf("请输入第%d位舞者的姓名和性别,用空格隔开(F表示女,M表示男)\n",i+1);
                scanf("%s %c",&wuzhe[i].name,&wuzhe[i].male);
        }
        dance(wuzhe,n);
        return 0;
}
感谢

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-4-25 14:13:55 | 显示全部楼层
队列满和队列空的判断逻辑问题:full 函数返回 1 表示满,但是判断条件应返回非0值表示真(在 C 中常用),return -1 会被认为是假,这与预期相反。
empty 函数逻辑也是反的,return -1 表示队列为空时实际应返回真(1),但返回了假(-1)。

pop 函数中的逻辑错误:在检查队列是否空时,empty(st) 应该返回 1 时表示空,但是您的代码中使用了 !empty(st) 表示队列为空。

男女判断和性别输入错误处理逻辑错误:当性别为男('M')时,应该只进入男队列逻辑分支,但是代码当前会继续检查性别输入错误的逻辑。

修正后的部分关键代码:

  1. int full(S* st) {
  2.     return (st->rear + 1) % size == st->front;
  3. }

  4. int empty(S* st) {
  5.     return st->rear == st->front;
  6. }

  7. int enter(S* st, people person) {
  8.     if (full(st)) {
  9.         printf("队列已满\n");
  10.         return 1;  // 队列满时返回1
  11.     }
  12.     st->ren[st->rear] = person;
  13.     st->rear = (st->rear + 1) % size;
  14.     return 0;  // 插入成功返回0
  15. }

  16. int pop(S* st, people* person) {
  17.     if (empty(st)) {
  18.         printf("空\n");
  19.         return 0;  // 队列空时返回0
  20.     }
  21.     *person = st->ren[st->front];
  22.     st->front = (st->front + 1) % size;
  23.     return 1;  // 弹出成功返回1
  24. }

  25. // 修改舞伴配对逻辑
  26. void dance(people dancers[], int n) {
  27.     S man, woman;
  28.     people person;
  29.     init(&man);
  30.     init(&woman);
  31.     int i;
  32.     for (i = 0; i < n; i++) {
  33.         if (dancers[i].male == 'F') {
  34.             enter(&woman, dancers[i]);
  35.         } else if (dancers[i].male == 'M') {
  36.             enter(&man, dancers[i]);
  37.         } else {
  38.             printf("性别输入错误:%s %c\n", dancers[i].name, dancers[i].male);
  39.         }
  40.     }
  41.     printf("舞伴配对如下\n");
  42.     while (!empty(&man) && !empty(&woman)) {
  43.         pop(&woman, &person);
  44.         printf("%s女士与", person.name);
  45.         pop(&man, &person);
  46.         printf("%s男士配对\n", person.name);
  47.     }
  48.     if (!empty(&man)) {
  49.         person = gethead(man);
  50.         printf("%s男士将在下一轮第一个获得匹配机会\n", person.name);
  51.     }
  52.     if (!empty(&woman)) {
  53.         person = gethead(woman);
  54.         printf("%s女士将在下一轮第一个获得匹配机会\n", person.name);
  55.     }
  56. }
复制代码

代码修正了队列判断逻辑,并调整了条件判断,以确保程序逻辑正确且不会陷入无限循环。

同时,确保了性别错误的逻辑仅在真正输入错误时才触发。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-5-8 14:28:31 | 显示全部楼层
6666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-30 02:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表