實現舞會上男女舞伴的自動匹配。

主要實現代碼


/****************************************************
  @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_

演示效果:

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章