后进先出 - 栈

​ 前面了解了队列,它是一种先进先出的数据结构,还有一种后进先出的数据结构,它叫做栈。栈限定为只能在一端进行插入和删除操作。比如说有一个小桶,小桶的直径只能放一个球,我们现在在桶内依次放入2,1,3号小球。假如你现在需要拿出2号小球,那就必须先把3号小球拿出,然后再拿出1号小球,最后拿出2号小球。在刚才取小球的过程中,我们最先放进去的小球最后才能拿出来,最后放进去的小球却可以最先拿出来。

​ 栈究竟有哪些作用?先看一个例子。xyzyx是一个回文字符串,所谓回文字符串就是指正反读均为相同的字符序列。通过栈这个数据结构,我们将很容易判断一个字符串是否为回文字符串。

​ 首先我们要读取这行字符串,并求这个字符串的长度:

char a[100];
int len;
gets(a);
len = strlen(a);

如果一个字符串是回文的话,那么它必须是中间对称的,我们需要求中心点,即:

mid = len / 2 - 1;

接下来就是要对mid之前的字符全部入栈。这里的栈是用来存储字符的,所以这里用来实现栈的字符数组即 char s[101],初始化栈很简单,top=0就可以了。入栈的操作时top++;s[top]=x;(假设我们要入栈的字符暂存在x中),其实就可以简写成s[top++] = x;现在我们将mid之前的字符依次入栈。

for (i = 0; i <= mid; i++) {
    s[top++] = a[i];
}

加下来就是判断回文的关键步骤。将当前栈的字符依次出栈,看看是否能和与mid之后的字符一一匹配,如果能匹配则说明这个字符串是回文字符串,否则这个字符串就不是回文字符串。

for (i = mid + 1; i <= len - 1; i++) {
    if (a[i] != s[top]) {
        break;
    }
    top--;
}
if (top == 0) {
    printf("YES");
} else {
    printf("NO");
}

完整代码如下:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[101], s[101];
    int i, len, mid, next, top;
    
    gets(a);
    len = strlen(a);
    mid = len / 2 - 1;
    
    top = 0; // 初始化栈
    // 将mid之前的字符全部入栈
    for (i = 0; i <= mid; i++) {
        s[top++] = a[i];
    }
    
    // 判断字符串长度是奇数还是偶数,找出需要进行字符匹配的起始下标
    if (len % 2 == 0) {
        next = mid + 1;
    } else {
        next = mid + 2;
    }
    
    // 开始匹配
    for (i = next; i <= len - 1; i++) {
        if (a[i] != s[top]) {
            break;
        }
        top--;
    }
    
    // 如果top的值为0,说明栈内所有的字符都被一一匹配了
    if (top == 0) {
        printf("YES");
    } else {
        printf("NO");
    }
    
    return 0;
}

可以输入回文字符串或者非回文字符串进行验证。
栈还可以用来进行验证括号是否匹配。在编程当中我们只会用到三种括号:圆括号,方括号和花括号,编译器在编译时会检查括号是否正确匹配。例如{[()]}、{()[]{}}都是合法的匹配,但是([)]是不合法的匹配。可以试着编写一个栈判断输入的括号序列是否合法,方法与判断回文字符串大致一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值