前面了解了队列,它是一种先进先出的数据结构,还有一种后进先出的数据结构,它叫做栈。栈限定为只能在一端进行插入和删除操作。比如说有一个小桶,小桶的直径只能放一个球,我们现在在桶内依次放入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;
}
可以输入回文字符串或者非回文字符串进行验证。
栈还可以用来进行验证括号是否匹配。在编程当中我们只会用到三种括号:圆括号,方括号和花括号,编译器在编译时会检查括号是否正确匹配。例如{[()]}、{()[]{}}都是合法的匹配,但是([)]是不合法的匹配。可以试着编写一个栈判断输入的括号序列是否合法,方法与判断回文字符串大致一样。