关于#算法#的问题,如何解决?

修改程序
题目如下
试设计一个算法,建立一个学生成绩栈或队列。要求从键盘上输入 N 个整数,按照下列要求分别进入不同栈或队列,并分别输出每个栈或队列的内容。

(1) 若输入的整数 x 小于 60 ,则进入第一个栈或队列;

(2) 若输入的整数 x 大于等于 60 ,小于 100 ,则进入第二个栈或队列;

(3) 若输入的整数 x 大于等于 100 ,则进入第三个栈或队列;
我的代码

#include
#include
# define OK 1
# define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int QElemType;
typedef struct QNode{
    QElemType data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;
Status InitQueue(LinkQueue *Q){
    //构造新的队列 
    Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));
    if(!Q->front) exit(OVERFLOW);
    Q->front->next=NULL;
    return OK;
}
Status EnQueue(LinkQueue *Q,QElemType e){
    //插入元素e为Q的新的队尾元素
    QueuePtr p;
    p=(QueuePtr)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);
    p->next=NULL;
    p->data=e;
    Q->rear->next=p;
    Q->rear=p;
    return OK; 
}
Status DeQueue(LinkQueue *Q,QElemType *e){
    //若队不空,删除Q的队头元素,并用e返回其值
    QueuePtr p;
    if(Q->front==Q->rear) return ERROR;
     p=(QueuePtr)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);
    p=Q->front->next;
    *e=p->data;
    Q->front->next=p->next;
    if(Q->rear==p) Q->rear=Q->front;
    free(p);
    return OK;
}
int main(){
    int n,a,i;
    char c;
    int m1=0,m2=0,m3=0;
    LinkQueue Q1, Q2,Q3;
    InitQueue(&Q1);
    InitQueue(&Q2);
    InitQueue(&Q3);
    scanf("%d",&n);
    for(i=0;iwhile(scanf("%d%c",&a,&c)==2&&c!='\n'){
            if(a<60)  EnQueue(&Q1,a);
            if(a>=60&&a<100) EnQueue(&Q2,a);
            if(a>=100) EnQueue(&Q3,a);
        }
    }
    DeQueue(&Q1,&m1);
    DeQueue(&Q2,&m2);
    DeQueue(&Q3,&m3);
     printf("60>x:");
        while(DeQueue(&Q1,&m1)==OK){
            printf(" %d ", m1);     
        }
        printf("\n");
        printf("60<=x<100:");
        while(DeQueue(&Q2,&m2)==OK){
            printf(" %d ", m2);     
        }
        printf("\n");
        printf("x>=100:");
        while(DeQueue(&Q3,&m3)==OK){
            printf(" %d ", m3);     
        }
        printf("\n");
     
    return 0;
}

我的问题
为啥把队列里的第一个数吞掉
No. 权重 时间限制 内存限制 测试输入 期待的输出 测试输出 错误信息 用时(秒) 内存 程序返回值 通过 测试结果
1 2 1秒 64M 以文本方式显示 下载
6↵
34 67 78 90 99 100↵
预设输出
60>x:34 ↵
60<=x<100:67 78 90 99 ↵
x>=100:100 ↵
我的输出
60>x:↵
60<=x<100: 78 90 99 ↵
x>=100:↵
请问为啥会出现错误

参考GPT和自己的思路:

在代码中,问题出现在第63-65行和第67-69行。

在第63-65行,你使用DeQueue函数将队列Q1中的元素依次出队,并将出队的元素存储在变量m1中,但是你并没有对变量m1进行任何操作,而是直接将其丢弃。因此,队列中的第一个元素就被“吞掉”了。

在第67-69行,你再次使用DeQueue函数,但这一次将队列Q1中的元素出队,并输出出队的元素。由于在第63-65行中已经将队列Q1中的所有元素出队,因此在第67-69行中,队列Q1已经为空,无法再次输出任何元素。

要解决这个问题,你需要修改代码。在第63-65行,应该在将出队的元素存储在变量m1中后,对其进行处理,例如在一个数组中存储起来,或者直接输出。在第67-69行,应该使用while循环将队列中的所有元素依次出队并输出。

以下是代码的修改建议:

在第63-65行后添加输出语句:

DeQueue(&Q1,&m1);
printf("%d ", m1);

在第67-69行中,将while循环改为if条件语句:

if(DeQueue(&Q1,&m1)==OK){
   printf(" %d ", m1);
}

修改后的完整代码如下:

#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2

typedef int Status;
typedef int QElemType;
typedef struct QNode{
  QElemType data;
  struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
  QueuePtr front;
  QueuePtr rear;
}LinkQueue;

Status InitQueue(LinkQueue *Q){
  //构造新的队列
  Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));
  if(!Q->front) exit(OVERFLOW);
  Q->front->next=NULL;
  return OK;
}

Status EnQueue(LinkQueue *Q,QElemType e){
  //插入元素e为Q的新的队尾元素
  QueuePtr p;
  p=(QueuePtr)malloc(sizeof(QNode));
  if(!p) exit(OVERFLOW);
  p->next=NULL;
  p->data=e;
  Q->rear->next=p;
  Q->rear=p;
  return OK;
}

Status DeQueue(LinkQueue *Q,QElemType *e){
  //若队不空,删除Q的队头元素,并用e返回其值
  QueuePtr p;
  if(Q->front==Q->rear) return ERROR;
  p=(QueuePtr)malloc(sizeof(QNode));
  if(!p) exit(OVERFLOW);
  p=Q->front->next;
  *e=p->data;
  Q->front->next=p->next;
  if(Q->rear==p) Q->rear=Q->front;
  free(p);
  return OK;
}

int main(){
  int n,a,i;
  char c;
  int m1=0,m2=0,m3=0;
  LinkQueue Q1, Q2,Q3;
  InitQueue(&Q1);
  InitQueue(&Q2);
  InitQueue(&Q3);
  scanf("%d",&n);
  for(i=0;i<n;i++){
    while(scanf("%d%c",&a,&c)==2&&c!='\n'){
      if(a<60) EnQueue(&Q1,a);
      if(a>=60&&a<100) EnQueue(&Q2,a);
      if(a>=100) EnQueue(&Q3,a);
    }
  }

  printf("60>x:");
  while(DeQueue(&Q1,&m1)==OK){
    printf("%d ", m1);
  }
  printf("\n");

  printf("60<=x<100:");
  while(DeQueue(&Q2,&m2)==OK){
    printf("%d ", m2);
  }
  printf("\n");

  printf("x>=100:");
  while(DeQueue(&Q3,&m3)==OK){
    printf("%d ", m3);
  }
  printf("\n");

  return 0;
}

调试一下你的代码,输入格式的代码

参考GPT和自己的思路:

可以发现,代码中的第63-65行是在每个队列中取出了一个元素,这样会导致第一个元素被取出后没法再输出了。这个问题可以通过在输出队列元素前先判断队列是否为空来解决。可以在第67、72、77行前加上判断队列是否为空的语句,如:

if(QueueEmpty(Q1)) break; // Q1为空时退出循环
DeQueue(&Q1,&m1);

其中,QueueEmpty(Q)是判断队列Q是否为空的函数。同样的,需要在第72、77行前进行判断。

另外,代码中第57行开始的while循环似乎是多余的,可以直接用if语句代替。最终修改后的代码如下:

#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int QElemType;
typedef struct QNode{
    QElemType data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;
Status InitQueue(LinkQueue *Q){
    //构造新的队列
    Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));
    if(!Q->front) exit(OVERFLOW);
    Q->front->next=NULL;
    return OK;
}
Status EnQueue(LinkQueue *Q,QElemType e){
    //插入元素e为Q的新的队尾元素
    QueuePtr p;
    p=(QueuePtr)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);
    p->next=NULL;
    p->data=e;
    Q->rear->next=p;
    Q->rear=p;
    return OK;
}
Status DeQueue(LinkQueue *Q,QElemType *e){
    //若队不空,删除Q的队头元素,并用e返回其值
    QueuePtr p;
    if(Q->front==Q->rear) return ERROR;
    p=(QueuePtr)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);
    p=Q->front->next;
    *e=p->data;
    Q->front->next=p->next;
    if(Q->rear==p) Q->rear=Q->front;
    free(p);
    return OK;
}

Status QueueEmpty(LinkQueue Q){
    //判断队列是否为空
    if(Q.front==Q.rear) return OK;
    else return ERROR;
}

int main(){
    int n,a,i;
    char c;
    int m1=0,m2=0,m3=0;
    LinkQueue Q1, Q2,Q3;
    InitQueue(&Q1);
    InitQueue(&Q2);
    InitQueue(&Q3);
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d",&a);
        if(a<60) EnQueue(&Q1,a);
        if(a>=60&&a<100) EnQueue(&Q2,a);
        if(a>=100) EnQueue(&Q3,a);
    }
    printf("60>x:");
    while(1){
        if(QueueEmpty(Q1)) break;
        DeQueue(&Q1,&m1);
        printf(" %d ", m1);
    }
    printf("\n");
    printf("60<=x<100:");
    while(1){
        if(QueueEmpty(Q2)) break;
        DeQueue(&Q2,&m2);
        printf(" %d ", m2);
    }
    printf("\n");
    printf("x>=100:");
    while(1){
        if(QueueEmpty(Q3)) break;
        DeQueue(&Q3,&m3);
        printf(" %d ", m3);
    }
    printf("\n");

    return 0;
}

这样,就可以正常输出队列中的所有元素了。