数据结构实验③:栈和队列的应用(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<stdio.h>
#include<stdlib.h>
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);
}

运行截图:

(2)【括号匹配问题】

步骤:

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

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

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

#include<stdio.h>
#include<stdlib.h>
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;
}

运行截图

(3)【舞伴匹配问题】

步骤:

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

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

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

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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;
}

运行截图:

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

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

  • 14
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

憨憨猿学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值