【发布时间】:2018-03-09 08:10:46
【问题描述】:
我是C的初学者,为了练习,决定参加一个小型的在线比赛。
在当前问题中,我被要求编写一个带有 struct 的队列,该队列响应命令 PushBack 和 PopFront。
输入包括
- 一个数字
n(n <= 1000000) 表示命令输入的数量。 -
n行。每行包含两个整数a和b:-
a是2用于执行PopFront,在这种情况下,b是预期的弹出值。 -
a是3forPushBack,在这种情况下,b是要排队的值。
-
如果我们尝试从空队列中弹出,则返回值是-1。
任务是在程序执行过程中任何PushBack返回的值是否与预期值一致,则在执行最后一条命令后打印YES或NO。
我实现了这个版本,但在提交我的答案后,在线评委给出了Maximum-Limit-Excedeed(在27的最后一次测试中)。
我正在阅读它,这个问题可能与其中一些有关:
- 使用过大的数组或数据结构。
- 程序中存在无限(或太大)递归。
- 指针使用不正确(诊断为 MLE)。
我不确定是什么问题。在我看来,在某些测试中,添加节点的数量远远大于删除(这意味着 1. 发生在我的代码中),这反过来又导致 @987654346 中的 while 循环@ 太大(2. 也会发生)。我无法发现指针的使用是否不正确。
我的问题是:
- 我在这里做错了什么?
- 我应该怎么做才能解决这个问题?
代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
//===================
//Definitions:
typedef int Item;
typedef struct node
{
Item item;
struct node * next;
} Node;
typedef struct queue
{
Node * front;
Node * rear;
long counter;
} Queue;
//===================
//Function Prototypes:
void InitializeQueue(Queue * pq);
bool PushBack(Queue * pq, Item item);
int PopFront(Queue * pq);
void EmptyQueue(Queue * pq);
int main(void)
{
Queue line;
long n, i;
int command, expected, received;
bool check = true;
scanf("%ld", &n);
InitializeQueue(&line);
i = 0;
while (i < n)
{
scanf("%d %d", &command, &expected);
switch (command)
{
case 2:
received = PopFront(&line);
if (received != expected)
check = false;
break;
case 3:
PushBack(&line, expected);
break;
}
i++;
}
if (check == true)
printf("YES\n");
else
printf("NO\n");
// free memory used by all nodes
EmptyQueue(&line);
return 0;
}
void InitializeQueue(Queue * pq)
{
pq->front = NULL;
pq->rear = NULL;
pq->counter = 0;
}
bool PushBack(Queue * pq, Item item)
{
Node * pnode;
//Create node
pnode = (Node *)malloc(sizeof(Node));
if (pnode == NULL)
{
fputs("Impossible to allocate memory", stderr);
return false;
}
else
{
pnode->item = item;
pnode->next = NULL;
}
//Connect to Queue
if (pq->front == NULL)
{
pq->front = pnode;
pq->rear = pnode;
}
else
{
pq->rear->next = pnode;
pq->rear = pnode;
}
pq->counter++;
return true;
}
int PopFront(Queue * pq)
{
int popped;
Node * temp;
temp = pq->front;
if (pq->counter == 0)
return -1;
else
{
popped = pq->front->item;
pq->front = pq->front->next;
free(temp);
pq->counter--;
return popped;
}
}
void EmptyQueue(Queue * pq)
{
int dummy;
while (pq->counter != 0)
dummy = PopFront(pq);
}
谢谢。
【问题讨论】:
-
触发问题的确切输入是什么?
-
@MichaelWalz 未显示):。查看测试列表时,前 26 个给出了
ok,平均执行时间为 2 毫秒,(我猜)内存使用量为 380.00Kb。最后的测试给出了MLE,执行时间为 98ms,内存使用量为 5.14Mb。 -
我说你管理这种问题不需要管理链表。你不需要节点。管理指向内存区域的指针并将其复制到“基指针”中就足够了。当你压入一个值时,你在内存中设置一个值并增加内存指针,当你弹出值时,你减少内存指针并读取值。当内存指针等于“基指针”时,堆栈中没有任何内容。
-
在 PushBack() 中,看起来您正在覆盖值。您需要转到列表的头部/尾部,然后添加新分配的节点。
-
@MayurK,被覆盖的“值”是用于操作列表的指针。我不相信这有什么问题。
标签: c data-structures queue