编写病人看病模拟程序

编写病人看病模拟程序

目的:掌握队列应用的算法设计

内容:编写一个程序,反应病人到医院排队看医生的情况。在病人排队过程中主要重复下面两件事。
1:病人到达诊室,将病历本交给护士,排到等待队列中候诊。
2:护士从等待队列中取出下一位病人的病例,该病人进入诊室候诊。
要求模拟病人等待就诊这一过程。程序采用菜单方式,其选项及功能说明如下:
1):排队——输入排队病人的病历号,加入到病人排队队列中;
2):就诊——病人排队队列中最前面的病人就诊,并将其从队列中删除;
3):查看排队——从队首到队尾列出所有的排队病人的病历号;
4):不再排队,余下依次就诊——从队首到队尾列出所有的排队病人的病历号,并退出运行。
5):下班——退出运行。

思路:因为没有限制排队人数,故采用链队结构,然后利用队列的基本操作实现程序的功能。

定义结构体:
typedef long long int Elemtype;	//该队列中的元素超长整型
typedef struct Quene* List;	//将该队列结点的指针命名为List
typedef struct LinkQuene* SqList;	//将该队列类型的指针命名为SqList
struct Quene			//定义结点
{
	Elemtype data;	//存放病历号
	List next;			//下一个结点指针
};
struct LinkQuene
{
	List front;	//指向队首结点
	List rear;	//指向队尾结点
};
算法实现
bool Test(SqList q)
{
	int n;
	List p;
	bool flag = false;	//是否关闭程序,默认为“否”
	Elemtype e;
	InitQuene(q);	//创建链队
	menu();			//输出菜单
	while (scanf_s("%d", &n) != EOF) {
		switch (n) {
			case 1:printf("请输入您的病历号(不超过十位的整数):");
				scanf_s("%lld", &e);
				while (e > 1e10) {
					printf("\n病历号不合规,重新输入:");
					scanf_s("%lld", &e);
				}
				enQuene(q, e);	//将病历号入队
				printf("\n排队成功。\n");
				break;
			case 2:if (!QueneEmpty(q)) {
					deQuene(q, e);	//当有人排队,即队不为空时出队
					printf("就诊成功。\n");
				}
				else
					printf("当前无人排队。\n");
				break;
			case 3:p = q->front;	//遍历一遍链队
				printf("排在您前面的人有:\n");
				while (p != NULL) {
					printf("%lld\n", p->data);
					p = p->next;
				}
				break;
			case 4:p = q->front;	//遍历一遍链队
				printf("排在您前面的人有:\n");
				while (p != NULL) {
					printf("%lld\n", p->data);
					p = p->next;
				}
				flag = true;
				break;
			case 5:flag = true;
				break;
			default:printf("指令错误,重新输入。\n");
		}
		if (flag)
			break;
		menu();
	}
	DestroyQuene(q);	//销毁链队
	return true;
}
与主函数相结合
#include<stdio.h>	//输入输出头文件
#include<stdlib.h>	//标准头文件
#include<string.h>	//字符串头文件
#include<stdbool.h>	//布尔类型头文件

typedef long long int Elemtype;	//该队列中的元素超长整型
typedef struct Quene* List;	//将该队列结点的指针命名为List
typedef struct LinkQuene* SqList;	//将该队列类型的指针命名为SqList
struct Quene			//定义结点
{
	Elemtype data;	//存放病历号
	List next;			//下一个结点指针
};
struct LinkQuene
{
	List front;	//指向队首结点
	List rear;	//指向队尾结点
};

bool InitQuene(SqList& q);				//初始化队列
bool DestroyQuene(SqList& q);			//销毁队列
bool QueneEmpty(SqList& q);				//判断队列是否为空
bool enQuene(SqList& q, Elemtype& e);	//进队列
bool deQuene(SqList& q, Elemtype& e);	//出队列
bool Test(SqList q);					//病人看病模拟程序
void menu(void);						//菜单

int main(int argc, const char* argv[])
{
	SqList q = NULL;
	bool flag = Test(q);
	if (flag)
		printf("谢谢使用,再见。\n");
	return 0;
}
bool Test(SqList q)
{
	int n;
	List p;
	bool flag = false;	//是否关闭程序,默认为“否”
	Elemtype e;
	InitQuene(q);	//创建链队
	menu();			//输出菜单
	while (scanf_s("%d", &n) != EOF) {
		switch (n) {
			case 1:printf("请输入您的病历号(不超过十位的整数):");
				scanf_s("%lld", &e);
				while (e > 1e10) {
					printf("\n病历号不合规,重新输入:");
					scanf_s("%lld", &e);
				}
				enQuene(q, e);	//将病历号入队
				printf("\n排队成功。\n");
				break;
			case 2:if (!QueneEmpty(q)) {
					deQuene(q, e);	//当有人排队,即队不为空时出队
					printf("就诊成功。\n");
				}
				else
					printf("当前无人排队。\n");
				break;
			case 3:p = q->front;	//遍历一遍链队
				printf("排在您前面的人有:\n");
				while (p != NULL) {
					printf("%lld\n", p->data);
					p = p->next;
				}
				break;
			case 4:p = q->front;	//遍历一遍链队
				printf("排在您前面的人有:\n");
				while (p != NULL) {
					printf("%lld\n", p->data);
					p = p->next;
				}
				flag = true;
				break;
			case 5:flag = true;
				break;
			default:printf("指令错误,重新输入。\n");
		}
		if (flag)
			break;
		menu();
	}
	DestroyQuene(q);	//销毁链队
	return true;
}
void menu(void)
{
	printf("==========================\n");
	printf("=======选择您的操作=======\n");
	printf("==    1.排队            ==\n");
	printf("==    2.就诊            ==\n");
	printf("==    3.查看排队        ==\n");
	printf("==    4.不再排队        ==\n");
	printf("==    5.下班            ==\n");
	printf("==========================\n");
}
bool InitQuene(SqList& q)
{
	q = (SqList)malloc(sizeof(LinkQuene));
	//malloc有一定几率申请空间失败,此时继续申请,直到申请成功
	while (!q) {
		q = (SqList)malloc(sizeof(Quene));
	}
	q->front = q->rear = NULL;	//此时队列无元素(两个下标之间差的绝对值为0)
	return true;
}
bool DestroyQuene(SqList& q)
{
	List p;		//工作指针
	while (q->front != q->rear) {	//当队列中的结点大于一个时循环
		p = q->front;				//工作指针指向队首结点
		q->front = q->front->next;	//队首结点后移
		free(p);					//释放掉工作指针指向的结点
	}
	p = q->front;
	free(p);	//释放掉最后一个结点
	free(q);	//释放掉链队结点
	return true;
}
bool QueneEmpty(SqList& q)
{
	return (q->front == NULL);	//当队列为空时返回“真”,否则返回“假”
}
bool enQuene(SqList& q, Elemtype& e)
{
	List p = (List)malloc(sizeof(Quene));
	//malloc有一定几率申请空间失败,此时继续申请,直到申请成功
	while (!p) {
		p = (List)malloc(sizeof(Quene));
	}
	p->data = e;
	p->next = NULL;
	if (q->rear == NULL)
		q->front = q->rear = p;	//当链队为空时,新结点既是头结点又是尾结点
	else {
		q->rear->next = p;	//将新结点接到队尾
		q->rear = p;		//队尾移动
	}
	return true;
}
bool deQuene(SqList& q, Elemtype& e)
{
	if (q->front == NULL)  //当队列为空时无法出队,返回“假”
		return false;
	List p = q->front;	//工作指针指向队首
	if (q->front == q->rear)	//当链队中只有一个结点时
		q->front = q->rear = NULL;
	else						//当链队中有一个以上的结点时
		q->front = q->front->next;
	e = p->data;
	free(p);
	return true;
}
  • 11
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计的实现,以及它们在MATLAB环境的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述提到的`common_esprit_method1.m`和`common_esprit_method2.m`是种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值