这两天在网上看到这个题目,感觉挺有意思,就做了一下。我在网上看到其他人都是用C++做的,因为不懂C++语言,没看懂,尝试着用C语言做了该题。希望能来看该题的大神指点指点,估计还有些bug没找出来。
本人编程基础差,利用闲暇的时间来做此题,总时间加在一起,花了一天左右吧。网上有人花了半小时做完该题,让我膜拜啊,太佩服。
进入正题吧,题目要求如下: 实现一个简易的银行排号叫号系统
get 取号 示例:"get"或"get vip"
call 叫号 示例:"call"
delete 删除号码 示例:"delete 5"
count 获取当前排队总人数 示例:"count"
countN 获取号码N以前的排队人数 示例:"countN"
reset 重置排号机 示例:"reset"
quit 退出排号机 示例:"quit"
运行时间限制: 无限制
内存限制: 无限制
输入:
每行只会有一条输入(比如:C语言可使用gets函数获取一行输入命令的字符串)。
a、若输入不符合要求(如:命令字非法,或其他认为输入的错误)均需输出"error"
b、每条输出后使用换行符隔开(如后面示例)
输出:
1、取号。可获取普通号和vip号码。如初始状态,输入"get",则获取普通号码,执行结果为"1",如再次输入"get vip",则获取VIP号码,执行结果为"vip 2"。如果末尾的2号被删除,则再次调用"get"时应输出"2"。VIP号码有绝对的优先级。普通号和vip号码统一编号,取号均为连续号码。号码从1开始编号,最大为100000.
2、叫号。获取当前应该处理用户的号码。例如当前排队号码为1 2 3 4 5 7,当输入"call",执行结果为"1",如1为vip号码,则为"vip 1".如果再连续调用6次,第六次执行结果应为"error"
3、删除号码。客户不想办理时可删除号码,叫号时则跳过此号码。例如当前排队号码为1 2 3 4 5,输入"delete 5",执行结果为"5",如果5为vip则显示"vip 5"。再次输出"delete 5",执行结果为"error"
4、获取当前排队总人数。获取当前排队人数。例如当前排队号码为1 2 3 4 5 6,执行结果为"6"
5、获取在某个号码之前排队的总人数。例如当前排队号码为1 2 3 4 5 7,输入"countN 7",执行结果为"5"vip 4
本人实现的思路:构造一个数据链表,用data存当前的位号,vip表示是否为vip号码(1:是,0:否)然后构造相应操作的子函数,来对整个链表进行操作。也曾想过用数组的方式来实现,但想了一会没想出来,还是觉得用链表的方式实现要方便一些。
typedef struct Node{
int data;
int vip;
struct Node *next;
}Node,*pNode;
对于终端命令的输入,采用gets()和strtok()函数来处理。
在各子函数处理时,要注意题目的一些要求。稍微复杂一点的函数是叫号call和删除delete函数,这两种情况都要对最后一个节点单独处理,另外取号get需要考虑vip的情况。所以的子函如下所示,包括命令解析、链表头初始化、相应的操作函数。
pNode InitList(void);
int command(pNode pHead, char *substr1, char *substr2);
pNode get(pNode pHead,int vip);
pNode call(pNode pHead);
int delete_num(pNode pHead, int num);
int count(pNode pHead);
int countN(pNode pHead,int num);
int reset(pNode pHead);
int quit(pNode pHead);
在输出error格式上,调试时为了知道是哪里的error,并没有按照题目的格式要求输出,加了位置信息。另外一点题目要求排号上限不超过100000,本人作答时没有考虑该条件。如果需要加条件限制的话,就在get函数中加一个判断GetNumFlag的语句即可。
附上完整的源码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
/***********************************
定义链表结构体,用来存号、存VIP标志
************************************/
typedef struct Node{
int data;
int vip;
struct Node *next;
}Node,*pNode;
#define VIP 1
#define NOTVIP 0 //宏定义VIP的标志位
int GetNumFlag=0; //定义的全局变量,用来存储取号的数量,避免没人取号的情况下call完所有人后从1开始计数。
pNode InitList(void);
int command(pNode pHead, char *substr1, char *substr2);
pNode get(pNode pHead,int vip);
pNode call(pNode pHead);
int delete_num(pNode pHead, int num);
int count(pNode pHead);
int countN(pNode pHead,int num);
int reset(pNode pHead);
int quit(pNode pHead);
/***********************************************************************************
功能:主函数main
************************************************************************************/
int main()
{
char Str[20],StrBack[20];
char *substr1,*substr2;
pNode pHead=NULL;
pHead=InitList();
while(1){
gets(Str);
substr1=strtok(Str," ");
substr2=strtok(NULL," ");
if(command(pHead, substr1,substr2) == -1){
break;
}
}
return 0;
}
/***********************************************************************************
功能:解析命令函数
传入参数:pHead是链表头结点,substr1是命令第1个字串,substr2是命令第2个字串
返回值:正常返回0;返回-1时,表示收到了quit命令,退出排号机
************************************************************************************/
int command(pNode pHead, char *substr1, char *substr2)
{
int countNum=0;
if(substr1 == NULL){
printf("input error\n");
return 0;
}
if(strcmp(substr1,"get")==0){
if(substr2 != NULL ){
if(strcmp(substr2,"vip")==0){
get(pHead,VIP);
}else
printf("input error\n");
}else
get(pHead,NOTVIP);
}else if(strcmp(substr1,"call")==0){
call(pHead);
}else if(strcmp(substr1,"delete")==0){
if(substr2 != NULL ){
delete_num(pHead, (int)atol(substr2));
}else
printf("input error\n");
}else if(strcmp(substr1,"count")==0){
countNum=count(pHead);
printf("the count is: %d\n",countNum);
}else if(strcmp(substr1,"countN")==0){
if(substr2 != NULL ){
countNum=countN(pHead, (int)atol(substr2));
if(countNum == -1)
printf("input N is error\n",countNum);
else
printf("the countN is: %d\n",countNum);
}else
printf("input error\n");
}else if(strcmp(substr1,"reset")==0){
reset(pHead);
}else if(strcmp(substr1,"quit")==0){
quit(pHead);
return -1;
}else
printf("input error\n");
return 0;
}
/***********************************************************************************
功能:初始化链表头
传入参数:无
返回值:返回链表头指针pHead,如果初始化失败,则返回NULL指针
************************************************************************************/
pNode InitList(void)
{
pNode pHead = NULL;
pHead = (pNode)malloc(sizeof(Node));
if(pHead == NULL){
printf("fail to init list!\n");
return NULL;
}
pHead->data=0;
pHead->vip=0;
pHead->next=NULL;
return pHead;
}
/***********************************************************************************
功能:取号
传入参数:链表头指针pHead,vip为vip客户标志
返回值:返回链表头指针pHead,如果初始化失败,则返回NULL指针
************************************************************************************/
pNode get(pNode pHead,int vip)
{
pNode pNew,pTemp;
pTemp = pHead;
while(pTemp->next !=NULL){
pTemp = pTemp->next;
}
/****注意这里的可能错误,申请的内存是结构体的内存,pNode是指针,sizeof(pNode)为4,是指针的大小。因此在free的时候会出现程序崩溃,反而在申请内存和赋值时是没问题的,需要注意****/
// pNew = (pNode)malloc(sizeof(pNode));
pNew = (pNode)malloc(sizeof(Node));
if(pNew == NULL){
printf("fail to create pNew!\n");
return NULL;
}
pTemp->next = pNew;
pNew->next = NULL;
pNew->data = ++GetNumFlag;
// pNew->data = pTemp->data+1; //用这种情况,就会出现当call完所有数据后,get时从1开始计数,我猜银行系统会避免这种情况
if(vip==1){
pNew->vip = 1;
printf("get vip %d\n",GetNumFlag);
}else{
pNew->vip = 0;
printf("get %d\n",GetNumFlag);
}
return pNew;
}
/***********************************************************************************
功能:叫号,如果为vip需要输出vip标志
传入参数:链表头指针pHead
返回值:返回链表头指针pHead,如果所有号被叫完,再次叫号则返回NULL指针
************************************************************************************/
pNode call(pNode pHead)
{
pNode pTemp;
pNode pTempFront;
if(pHead->next == NULL){
printf("output error,number is over\n");
return NULL;
}
pTempFront = pHead;
pTemp = pHead->next;
while(pTemp->next != NULL || pTemp->vip ==VIP){ //首先获取VIP号码,注意当最后一个号为VIP的情况,不能跳过
if(pTemp->vip == VIP){
printf("this is vip: %d\n",pTemp->data);
if(pTemp->next !=NULL)
pTempFront->next = pTemp->next;
else
pTempFront->next = NULL;
free(pTemp);
pTemp = NULL;
return pHead;
}else{
pTempFront = pTemp;
pTemp = pTemp->next;
}
}
pTempFront = pHead;
pTemp = pHead->next;
printf("this is call: %d\n",pTemp->data);
pTempFront->next = pTemp->next;
free(pTemp);
pTemp = NULL;
return pHead;
}
/***********************************************************************************
功能:删除号码
传入参数:链表头指针pHead,num为需要删除的号码
返回值:成功返回0,如果未找到输出error并返回-1
************************************************************************************/
int delete_num(pNode pHead, int num)
{
int i=0;
pNode pTempFront,pTemp;
pTempFront=pHead;
pTemp=pTempFront->next;
while(pTemp->next != NULL){
if(pTemp->data == num ){
if(pTemp->vip == VIP){
printf("delete the num: vip %d\n",pTemp->data);
}else
printf("delete the num: %d\n",pTemp->data);
pTempFront->next = pTemp->next;
free(pTemp);
pTemp = NULL;
return 0;
}else{
pTemp=pTemp->next;
pTempFront=pTempFront->next;
}
}
if(pTemp->data == num ){ //这里要要判断最后一个节点,最后一个节点的处理有点区别,注意题目要求
if(pTemp->vip == VIP){
printf("delete the num: vip %d\n",pTemp->data);
}else
printf("delete the num: %d\n",pTemp->data);
pTempFront->next = pTemp->next;
free(pTemp);
pTemp = NULL;
GetNumFlag--; //这里要注意,题目要求:如果末尾的2号被删除,则再次调用"get"时应输出"2"
return 0;
}else{
printf("error,input number is not match\n");
return -1;
}
}
/***********************************************************************************
功能:获取当前排队总人数
传入参数:链表头指针pHead
返回值:返回当前排队总人数count
************************************************************************************/
int count(pNode pHead)
{
int count=0;
pNode pTemp=pHead;
while(pTemp->next != NULL){
count++;
pTemp=pTemp->next;
}
return count;
}
/***********************************************************************************
功能:获取N号以前的排队人数
传入参数:链表头指针pHead
返回值:返回N号以前的排队人数count,如果没有此号或者已经删除了此号,输出error,返回-1
************************************************************************************/
int countN(pNode pHead,int num)
{
int count=0;
pNode pTemp=pHead->next;
while(pTemp->data != num){
count++;
if(pTemp->next == NULL){
printf("error\n");
return -1;
}
pTemp=pTemp->next;
}
return count;
}
/***********************************************************************************
功能:重置排号机,释放存号的节点,不能释放头结点pHead
传入参数:链表头指针pHead
返回值:返回0
************************************************************************************/
int reset(pNode pHead)
{
pNode pTemp=pHead->next;
while(pHead->next != NULL){
pHead->next=pTemp->next;
free(pTemp);
pTemp=pHead->next;
}
GetNumFlag=0;
return 0;
}
/***********************************************************************************
功能:退出排号机,释放存号的节点,并且释放头结点pHead
传入参数:链表头指针pHead
返回值:返回0
************************************************************************************/
int quit(pNode pHead)
{
reset(pHead);
free(pHead);
return 0;
}
题目链接:HDU 5726题面:GCDTime Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1151 Accepted Submission(s): 354Problem Description
Spark的RDD转换算子-value型-coalesce、 repartition 、sortBy一、coalesce函数签名def repartition(numPartitions: Int)(implicit ord: Ordering[T] = null): RDD[T] 根据数据量缩减分区,用于大数据集过滤后,提高小数据集的执行效率 当 spark 程序中,存在过多的小任务的时候,可以通过 coalesce 方法,收缩合并分区,减少分区的个数,减小任务调度成本val rdd = sp
英语单词的记忆在英语学习中有着举足轻重的地位,可以说一个人掌握的单词量越多,英语水平就越高;而英语单词的记忆除了需要长时间不断地积累外,还需要高效的记忆方法。随着人们生活节奏的加快,人们也更希望通过信息技术可以用最短的时间记住最多的单词。也正是因为这样的需求,市面上出现了大量的背单词软件,虽然这些软件功能强大看起来也很气派,但是大部分都是通过各种手段来让人不断重复记忆的,并未以科学的方法从根本上解...
Google 与网络的帮助可以让你写出一行又一行的代码。不过,若你只是复制贴上,事后并没有尝试了解背后的运作机制,充其量代表了「工作完成」。那有什么办法可以让自己进步呢?也许你可以从少写一点代码开始。并不是要你不工作,而是想办法精简自己的代码。在某些方面,coding 跟写作有些类似,并不是多就是好,正如马克吐温说的:我没有时间写一封简短的信,所以我...
原文:http://www.cnblogs.com/rockics/archive/2010/12/20/1911784.htmlAPUE中的代码不是download下来就可以直接编译执行的。由于头文件的问题,需要做相关的设置,修改一下相关的文件。首先从http://www.apuebook.com/src.tar.gz下载源码压缩包,解压到相应目录,例如:mkdir /h
这道超级简单的题目没有任何输入。你只需要在第一行中输出程序员钦定名言“Hello World”,并且在第二行中输出更新版的“Hello New World”就可以了。PS:感谢github用户@zhuzihao-hz提供的pull request~print('Hello World')print('Hello New World') ...
S7-1200 PLC之间进行TCP通信的具体方法和步骤详解本次以一个1214 CPU和一个1215 CPU为例进行说明TCP通信的具体方法,其中1214作为发送端,1215作为接收端(也可以双方同时进行发送和接收,这里只是简单举例说明)如下图所示,新建一个项目,添加一个1214 CPU和1215CPU,双击“设备和网络”,选择“网络视图”,点击“连接”,选择“TCP连接”,如下图所示,如下图所示,直接用鼠标拖拽PN接口将2个CPU连接起来,松开即可,选中1214 CPU,进入属性—常规—
JqGrid中文文档最近使用JQGrid 发现其中文资料非常的少。几乎没有,而英文资料大部份是PHP。所以写一些资料方便自己和大家以后的使用。先来看一个我在官方网站复制的简单的例子。 1: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits=...
原文链接:http://www.juzicode.com/archives/2225错误提示:使用numpy.eye()函数时报NameError: name ‘numpy’ is not definedD:\juzicode>python mod.py 微信公众号: 桔子code / juzicode.com Traceback (most recent call last): File "mod.py", line 3, in n = numpy.eye(4)
一:文件系统1. 什么是文件系统?操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。通常文件系统是用于存储和组织文件的一种机制,便于对文件进行方便的查找与访问。文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。随着文件种类的增多,扩增了更多的文件系统,为了对各种文件系统进行统一的管理与组织。2. Linux文件系统Linux将文件系
dblink访问 ORA-00997: 非法使用 LONG 数据类型
一直以来都想搞个寄存器配置版本的ETH,最近时间充裕,花了近2周,昨天终于实现了以太网的连接,上图 捕获.JPG (28.93 KB, 下载次数: 0)下载附件 保存到相册 2018-3-23 10:48 上传 这是打印结果 下面详细说明一下 首先实现lan8742的驱动/* Ethernet pins configuration ********************************...