实现舞会上男女舞伴的自动匹配。

主要实现代码


/****************************************************
  @Title: 数据结构实验
  @Name: <实验3-4> <循环队列> 
  @Object:
      [实验目的] 循环队列的应用。
      [试验任务] 实现舞会上男女舞伴的自动匹配。
           舞会上先后到达男士和女士若干人,第一轮按照
           到来的先后顺序,男女搭配一组,如果有剩下的,
           等下一轮首先匹配。
           打印出1-3轮的匹配情况。 

      [实验提示] 
           1. 在文件 sqqueue.h 中完成循环队列的实现 

           2. 根据两个队列元素个数,如何计算能匹配
              多少对舞伴

           3. 前一轮尚未轮到的,在下一轮中先匹配,
              如何处理,要完成多轮匹配。
              提示:匹配后继续加入队列中。 
  @Files:
      app0304.cpp [*]
         测试循环队列的主程序 
      sqqueue.h [*]
         循环队列的实现 
      dance.txt [*]
         舞伴数据文件 
  @Usage:
      请查看"TO-DO列表",根据要求完成代码
  @Copyright: BTC 2004, Zhuang Bo
  @Author: Zhuang Bo
  @Date: 2004
  @Description:
*****************************************************/

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
struct Person {
    char name[20]; //名字 
    char sex;      //男'M';女'F'
};

#define ElemType Person /* 队列中数据元素的类型 */
#include "sqqueue.h"

////////////////////////////////////////////
//主程序 
void du();
void pipei();
SqQueue maleDancers, femaleDancers;
void main()
{
     InitQueue(maleDancers);
    InitQueue(femaleDancers);
    //用两个队列存放男士和女士

    //从文件dance.txt中读取数据

    //匹配舞伴
     //计算并打印出1-3轮的匹配结果 
    for(int round=0; round<3; round++) {
        /* TODO (#1#): 计算并打印第round轮匹配结果 */
        du();
        pipei();
        //------------------------------------------
    }


    system("pause"); //暂停 
}
void du(){
    FILE *fin=0;
    if((fin=fopen("dance.txt","r"))==0) {
        printf("错误: 不能打开文件 dance.txt\n"); 
        exit(1);
    }
    while(!feof(fin)) {
        //读出一条记录 
        Person p;
        p.sex = fgetc(fin);
        fgets(p.name, 20, fin);
        //printf("%c",p.sex);
        /* TODO (#1#): 根据性别将 p 加入对应的队列 */
        if(p.sex=='F'){
            EnQueue(femaleDancers, p);
        }
        else{
            EnQueue(maleDancers, p);
        }
        //------------------------------------------
    }
    }
void pipei(){
    Person p1,p2;
    int npair; //一轮中匹配舞伴数(对)
    /* TODO (#2#): 计算能够匹配多少对舞伴 */
    for(npair=0;(!QueueEmpty(femaleDancers))&&(!QueueEmpty(maleDancers));npair++){
        GetHead(femaleDancers, p1);
        GetHead(maleDancers, p2);
        printf("匹配成功,男:%s 女:%s\n",p2.name,p1.name);
        DeQueue(femaleDancers, p1);
        DeQueue(maleDancers, p2);
    }
    printf("第一匹配数%d\n",npair);
    printf("匹配结束");
    // npair = -------------------------------------
    }

////////////////////////////////////////////
//函数的定义 


/*
  Name: 循环队列 
  Copyright: BTC 2004
  Author: Zhuang Bo
  Date: 2004
  Description:
     [Include] 
        ds.h
     [Constants]
        MAXQSIZE
     [Types]
        ElemType
        SqQueue
     [Functions]
        InitQueue(&Q)
        DestroyQueue(&Q)
        ClearQueue(&Q)
        QueueEmpty(Q)
        QueueLength(Q)
        GetHead(Q,&e)
        EnQueue(&Q,e)
        DeQueue(&Q,&e)
     [For Debug]
        PrintElem(ElemType e)
        QueueView(Q)
*/

#ifndef SQQUEUE_H_INCLUDED
#define SQQUEUE_H_INCLUDED /* 防止重复包含 */

//////////////////////////////////////////
//包含头文件 
#include <stdlib.h>
#include "ds.h" // OK, Status 等定义 

//数据元素的类型(缺省使用int型)
#ifndef ElemType
#define ElemType int
#define USE_DEFAULT_ELEMTYPE /* 使用缺省类型的标志 */
#endif //ElemType

//////////////////////////////////////////
//循环队列的存储结构

#define MAXQSIZE 64 /* 循环队列的最大容量 */
typedef struct {
    /* TODO (#1#): 这里完成循环队列的类型定义 */
    ElemType *base;
    int front;
    int rear;
    //....................................
} SqQueue;


//////////////////////////////////////////
//循环队列的基本操作 

//构造一个空队列Q
Status InitQueue(SqQueue &Q)
{
    /* TODO (#2#): 构造空队列 */
    Q.base=(ElemType*)malloc(MAXQSIZE*sizeof(ElemType));
    if(!Q.base){
        exit(0);
    }
    Q.front=Q.rear=0;
    return OK; //TODO: 替换这行代码,以下同
    //....................................
}

//销毁队列Q 
//  前提:队列Q已存在 
Status DestroyQueue(SqQueue &Q)
{
    /* TODO (#3#): 销毁队列 */
    if(Q.base){
        free(Q.base);
        return OK;
    }
    else
        return ERROR;

    //....................................
}

//将队列Q清为空队列
//  前提:队列Q已存在
Status ClearQueue(SqQueue &Q)
{
    /* TODO (#4#): 清空队列 */
    if(Q.base){
        Q.front=Q.rear;
        return  OK;
    }
    else
        return ERROR;
    //....................................
}

//若队列Q为空,则返回TRUE,否则FALSE 
//  前提:队列Q已存在
Status QueueEmpty(SqQueue Q)
{
    /* TODO (#5#): 判断队列是否为空 */
    if(Q.rear==Q.front){
        return TRUE; 
    }
    return FALSE;
    //....................................
}

//返回队列Q的元素个数,即队列长度
//  前提:队列Q已存在 
int QueueLength(SqQueue Q)
{
    /* TODO (#6#): 返回队列长度 */

    return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
    //....................................
}

//取队列Q头元素用e返回
//  前提:队列Q存在且非空
Status GetHead(SqQueue Q, ElemType &e)
{
    /* TODO (#7#): 取队头元素存入e */
    if(Q.front==Q.rear){//队列为空
        return ERROR;      
    }
    e=Q.base[Q.front];
    return OK;//返回操作状态(成功:OK,失败:ERROR)
    //....................................
}

//插入元素e作为队列Q的新的队尾元素
//  前提:队列Q存在且未满
Status EnQueue(SqQueue &Q, ElemType e)
{
    /* TODO (#8#): 元素e入队列 */
    if((Q.rear+1)%MAXQSIZE==Q.front){
        return ERROR;
    }
    Q.base[Q.rear]=e;
    Q.rear=(Q.rear+1)%MAXQSIZE;
    return OK;//返回操作状态(成功:OK,失败:ERROR)
    //....................................
}

//删除队列Q的队头元素,并用e返回 
//  前提:队列Q存在且非空 
Status DeQueue(SqQueue &Q, ElemType &e)
{
    /* TODO (#9#): 出队列存入e */
    if(Q.front==Q.rear){
        return ERROR;
    }
    e=Q.base[Q.front];
    Q.front=(Q.front+1)%MAXQSIZE;
    return OK ;//返回操作状态(成功:OK,失败:ERROR)
    //....................................
}

//////////////////////////////////////////

//TODO: 定义好 SqQueue 类型后使用 QueueView 函数 

#include <stdio.h>
//查看队列状态(调试用)
void QueueView(SqQueue Q)
{
   //extern void PrintElem(ElemType e);//打印数据用 
   int i=0;
   if(Q.front<0||Q.front>=MAXQSIZE||Q.rear<0||Q.rear>=MAXQSIZE){
       printf("队列未初始化\n"); 
       return ;
   }
   printf("---Queue View---\n");
   printf("front=%d , rear=%d\n", Q.front, Q.rear);
   if(Q.rear>=Q.front) {
       printf(".....   ......\n");
       for(i=Q.front; i<Q.rear; i++) {
           printf("%5d\t", i);
           printf("%d",Q.base[i]);
           printf("\n");
       }
       if(i<MAXQSIZE) printf(".....   ......\n");
   } else {       
       for(i=0; i<Q.rear; i++) {
           printf("%5d\t", i);
           printf("%d",Q.base[i]);
           printf("\n");
       }
       printf(".....   ......\n");
       for(i=Q.front; i<MAXQSIZE; i++) {
           printf("%5d\t", i);
           printf("%d",Q.base[i]);
           printf("\n");
       }
   }
   printf("--- view end ---\n");
}


//取消ElemType的默认定义,以免影响其它部分 
#ifdef USE_DEFAULT_ELEMTYPE
#undef ElemType
#undef USE_EFAULT_ELEMTYPE
#endif

#endif //SQQUEUE_H_INCLUDED

/*
  Name: 类C通用模块 
  Copyright: BTC 2004
  Author: Zhuang Bo
  Date: 2004
  Description:  
    [Constants]
       TRUE/FALSE/OK/ERROR/INFEASIBLE/OVERFLOW      
    [Types]  
       Status      
    [Functions]
       max(a,b)
       min(a,b)
       read(char/int/float/double/char*)
       write(char/int/float/double/char*)
*/

#ifndef _DS_H_
#define _DS_H_

// 函数结果状态代码
const int TRUE      = 1;
const int FALSE     = 0;
const int OK        = 1;
const int ERROR     = 0;
const int INFEASIBLE    = -1;
const int OVERFLOW      = -2;

// Status 是函数的类型,其值是函数结果状态代码
typedef int Status;

//基本函数
#define max(a,b) (((a)<(b))?(b):(a)) 
#define min(a,b) (((a)<(b))?(a):(b))

#include <stdio.h>
//不用格式串的输入输出(目的是为了方便书写算法)
//    比如输入一个基本类型(char, int, float, double, char*)的
//    变量 x,可以直接用 read(x);输入,而打印则用 write(x);。 
//    对于自定义类型,可以继续扩充。
inline void read(char& e)     { e = getchar(); }
inline void read(int& e)      { scanf("%d", &e); }
inline void read(float& e)    { scanf("%f", &e); }
inline void read(double& e)   { scanf("%lf", &e); }
inline void read(char *e)     { gets(e); }
inline void write(char e)     { printf("%c", e); }
inline void write(int e)      { printf("%d", e); }
inline void write(float e)    { printf("%f", e); }
inline void write(double e)   { printf("%lf", e); }
inline void write(char *e)    { printf("%s",e); }

#endif  // _DS_H_

演示效果:

这里写图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值