数据结构实验③:栈和队列的应用(C语言)【进制转换】【括号匹配问题】【舞伴匹配问题】

如果你喜欢这篇文章的话,请给作者点赞哟,你的支持是我不断前进的动力。

因为作者能力水平有限,欢迎各位大佬指导。

目录

(1)【进制转换问题】

(2)【括号匹配问题】

(3)【舞伴匹配问题】


一、题目描述

(1)、输入一个十进制数,利用栈操作,将该数转换成n进制数。以十进制整数转换为八进制数为例,在计算过程中,把N与8求余得到的八进制数的各位依次进栈,计算完毕后将栈中的八进制数依次出栈输出。

(2)、输入一个表达式,表达式中包括三种括号“()”、“[]”和“{}”,判断该表达式的括号是否匹配。检验算法借助一个栈,每当读入一个左括号,则直接入栈,等待相匹配的同类右括号;每当读入一个右括号,若与当前栈顶的左括号类型相同,则二者匹配,将栈顶的左括号出栈,直到表达式扫描完毕。

(3)、循环队列的应用——舞伴配对问题:在舞会上,男、女各自排成一队。舞会开始时,依次从男队和女队的队头各出一人配成舞伴。如果两队初始人数不等,则较长的那一队中未配对者等待下一轮舞曲。假设初始男、女人数及性别已经固定,舞会的轮数从键盘输入。试模拟解决上述舞伴配对问题。要求:从屏幕输出每一轮舞伴配对名单,如果在该轮有未配对的,能够从屏幕显示下一轮第一个出场的未配对者的姓名。

(1)【进制转换问题】

步骤:

核心算法:实现进制转换的操作以及栈的基本操作。

首先实现“栈初始化,栈空判断以及进栈和出栈”的基本操作。

进制转换:定义两个变量z和y,其中z表示要输入的数,y表示要转换的进制。在while循环的条件下,让z和y取余,之后进行z/y的操作,知道z为0,循环停止。在while循环的大条件下(判断栈是否为空)考虑到十六进制的特殊性,需要对十六进制进行另外的操作,使用if判断语句判断当前的e值是否为10,11,12,13,14,15,若为这些数,则输出其对应的A,B,C,D,E,F字符。来满足十六进制的特殊性。

主函数:调用不同的函数实现进制转换的最终目的,并进行一定的修改。

代码:

#include
#include
typedef struct
{
    int *base;
    int top;
    int stacksize;
} SqStack;

//初始化
void InitStack(SqStack &S)
{
    S.base = (int* ) malloc (100 * sizeof(int));
    if(!S.base)exit(0);
    S.top = 0;
    S.stacksize = 100;
}

//判空
int StackEmpty(SqStack S)
{
    if(S.top==0)
        return 1;
    else
        return 0;
}

//入栈
void Push(SqStack &S,int e)
{
    if(S.top >= S.stacksize)
    {
        S.base = (int* ) realloc (S.base,(S.stacksize + 10)*sizeof(int));
        if(!S.base)exit(0);
        S.stacksize += 10;
    }
    S.base[S.top++] = e;
}


//出栈
void Pop(SqStack &S,int &e)
{
    if(S.top == 0)
        return ;
    e = S.base[--S.top];
}

//进制转换
void Change(SqStack &S,int z,int y)
{
    int e;
    while(z)
    {
        Push(S,z%y);
        z=z/y;
    }
    while(!StackEmpty(S))
    {
        Pop(S,e);
        if(e == 10)
            printf("%c",'A');
        else if(e == 11)
            printf("%c",'B');
        else if(e == 12)
            printf("%c",'C');
        else if(e == 13)
            printf("%c",'D');
        else if(e == 14)
            printf("%c",'E');
        else if(e == 15)
            printf("%c",'F');
        else
            printf("%d",e);
    }
}
//主函数
int main()
{
    int a,b;
    SqStack S;
    InitStack(S);
    printf("请输入一个十进制数:");
    scanf("%d",&a);
    printf("请输入要转换的制数:");
    scanf("%d",&b);
    printf("转换为%d进制数:",b);
    Change(S,a,b);
}

运行截图:

数据结构实验③:栈和队列的应用(C语言)【进制转换】【括号匹配问题】【舞伴匹配问题】_第1张图片

(2)【括号匹配问题】

步骤:

核心问题:实现括号匹配函数

括号匹配:首先实现对栈的基本操作(初始化,判断栈空等),从左往右依次取字符串的字符,判断该字符是否为左括号,是则判断字符串是否结尾,否则判断该字符是否为右括号,是的话,判断与栈顶的左括号是否匹配?匹配则出栈,否则输出“括号不匹配”。使用while语句和switch以及if语句来实现。

代码:(英文输入法输入)

#include
#include
typedef struct
{
    char * top;
    char * base;
    int stacksize;
} SqStack;

//栈的初始化
void InitStack(SqStack &S)
{
    S.top = S.base = (char *) malloc (100 * sizeof(char));
    if(!S.base)exit(0);
    S.stacksize = 100;
}

//进栈
void Push(SqStack &S,char m)
{
    if(S.top-S.base >= S.stacksize)
    {
        S.base = (char* ) realloc (S.base,(S.stacksize + 5) * sizeof(char));
        if(!S.base)exit(0);
        S.top = S.base+S.stacksize;
        S.stacksize += 5;
    }
    *S.top++=m;
}


//出栈
void Pop(SqStack &S)
{
    if(S.base == S.top)exit(0);
    S.top--;
}
int StackEmlpty(SqStack s)
{
    if(s.top == s.base)
        return 1;
    else
        return 0;
}

//判断
void Match(char m[])
{
    SqStack S;
    int i=0;
    InitStack(S);
    while(m[i] != '\0')
    {
        switch(m[i])
        {
        case'(':
        case'[':
        case'{':
            Push(S,m[i]);break;
        case')':
            if(*(S.top-1) == '(') Pop(S);break;
        case']':
            if(*(S.top-1)=='[') Pop(S);break;
        case'}':
            if(*(S.top-1)=='{') Pop(S);break;
        }
        i++;
    }
    if(StackEmlpty(S))
        printf("括号匹配\n");
    else
        printf("括号不匹配\n");
}

//主函数
int main()
{
    char m[100];
    printf("请输入一串括号:");
    scanf("%s",m);
    Match(m);
    return 0;
}

运行截图

数据结构实验③:栈和队列的应用(C语言)【进制转换】【括号匹配问题】【舞伴匹配问题】_第2张图片

(3)【舞伴匹配问题】

步骤:

1.队列的基本操作(初始化等)。

2.舞伴配对思路:设置两个队列分别存放男女舞者的信息。使用scanf实现对舞者信息的录入功能。当两个队列的舞者信息录入完毕后,依次让两个队列当前的队头舞者出队结成舞伴,直到某一队列变为空为止。假如此时仍然有等待配对的舞者,需要输出这个队列中排在最前面的(即队头元素)舞者的名字,这个人就是下一轮舞曲开始的时候第一个可以获得另一队列里面排在当前最前面的舞者的配对权。

主函数:通过调用之前的函数实现最终舞者配对问题的实现,并对其进行一定的修改操作。

代码:

#include 
#include 
#include 
typedef struct Queue
{
    int Front;
    int Rear;
    char elem[100][100];
    int Queuesize;
} Queue;

//建立队列
void Creat(Queue &Q)
{
    int n,i;
    Q.Front = Q.Rear = 0;
    printf("请输入跳舞的人数:");
    scanf("%d",&n);
    Q.Queuesize = n+1;
    printf("请输入舞者的名字:");
    for(i = 0; i < n; i++)
    scanf("%s",&Q.elem[i]);
    Q.Rear=n;
}

//判断是否为空
int QueueEmpty(Queue Q)
{
    if(Q.Front == Q.Rear)
        return 1;
    else
        return 0;
}

//删除队头元素
void Delet(Queue &Q,char *str)
{
    strcpy(str,Q.elem[Q.Front]);
    Q.Front = (Q.Front + 1) % Q.Queuesize;
}

//取出队首元素
void Get(Queue Q,char *str)
{
    strcpy(str,Q.elem[Q.Front]);
}

//舞伴配对
void PeiDui(Queue &A,Queue &B)
{
    int n;
    char str1[100],str2[100];
    printf("请输入舞会的轮数:");
    scanf("%d",&n);
    while(n--)
    {
        while(!QueueEmpty(A))
        {
            if(QueueEmpty(B))
            Delet(B,str1);
            Delet(A,str1);
            Delet(B,str2);

            printf("\n配对的舞者有:%s<->%s\n",str1,str2);
        }
        A.Front=(A.Front+1)%A.Queuesize;
        if(QueueEmpty(B))
            Delet(B,str1);
        Get(B,str1);
        printf("下一轮第一个出场的未配对者:%s\n",str1);
    }
}

int main()
{
    Queue X,Y;
    printf("      男队\n");
    Creat(X);
    printf("      女队\n");
    Creat(Y);
    if(X.Queuesize>Y.Queuesize)
        PeiDui(Y,X);
    else
        PeiDui(X,Y);

    return 0;
}

运行截图:

数据结构实验③:栈和队列的应用(C语言)【进制转换】【括号匹配问题】【舞伴匹配问题】_第3张图片

如果你喜欢这篇文章的话,请给作者点赞哟,你的支持是我不断前进的动力。

因为作者能力水平有限,欢迎各位大佬指导。

你可能感兴趣的:(数据结构学习,数据结构实验,数据结构,c语言)