顺序栈
#include <string.h>
#include <iostream>
using namespace std;
#define STACKMAX 80
#define STACKADD 10
typedef int SElemtype;
typedef struct {
int *top;
int *base;
int stacksize;
} Sqstack;
bool initstack(Sqstack &s) {
s.base = (int *)malloc(STACKMAX * sizeof(int));
if (!s.base) {
return 0;
}
s.top = s.base;
s.stacksize = STACKMAX;
return 1;
}
bool push(Sqstack &s, int e) {
if (s.top - s.base >= s.stacksize) {
s.base = (int *)realloc(s.base, (s.stacksize + STACKADD) * sizeof(int));
if (!s.base) {
return 0;
}
s.top = s.base + s.stacksize;
s.stacksize += STACKADD;
}
*s.top++ = e;
return 1;
}
bool pop(Sqstack &s, int &e) {
if (s.top == s.base) {
return 0;
}
e = *s.top--;
return 1;
}
//链栈
typedef struct Snode {
int data;
struct Snode *next;
} Snode, *linkstack;
bool initstacklist(linkstack &s) {
s = (linkstack)malloc(sizeof(Snode));
if (!s) {
return 0;
}
// s->next = NULL;链栈出入都在栈顶,不去设置头节点,因此初始化没有这一步
return 1;
}
int stacklength(linkstack s) {
int length = 0;
linkstack p = s;
while (p) {
p = p->next;
length++;
}
return length;
}
bool pushstack(linkstack &s, int e) {
linkstack p = (linkstack)malloc(sizeof(Snode));
p->data = e;
p->next = s -> next;
s -> next = p;
s = p;
return 1;
}
bool popstack(linkstack &s, int &e) {
if (s == NULL) {
return 0;
}
linkstack p = s;
e = p->data;
s = p->next;
free(p);
return 1;
}
//Q1左右分隔符匹配问题,从左往右扫描待判断的C语言语句,如果左分隔符,把他压入栈中,如果是右分隔符,有两个情况1,当前栈非空,
//就弹出来左分隔符,看是否匹配.2,栈是空的,证明右分隔符多余,匹配失败。如果所有字符都读完发现栈还有东西,证明做分隔符多余,匹配失败
typedef char SElemtype[3];
int LEFT = 0;
int RIGHT = 1;
int OTHER = 2;
int verifyflag(char *str) { //判断符号类型的函数
if (!strcmp("(", str) || !strcmp("[", str) || !strcmp("{", str)
|| !strcmp("/*", str)) { //这里strcmp函数,如果匹配上返回0,所以加取反符
return LEFT;
}
if (!strcmp(")", str) || !strcmp("]", str) || !strcmp("}", str)
|| !strcmp("*/", str)) {
return RIGHT;
} else {
return OTHER;
}
}
bool matches(char *str1, char *str2) { //监测匹配的函数
if ((!strcmp("(", str1) && !strcmp(")", str2)) || (!strcmp("{", str1) && !strcmp("}", str2)) || (!strcmp("[", str1)
&& !strcmp("]", str2)) || (!strcmp("/*", str1) && !strcmp("*/", str2))) {
return true;
} else {
return false;
}
}
bool Islegal(char *str) {
if (str != NULL && strcmp(" ", str)) { //监测非空
Sqstack S;
initstack(S);
for (int i = 0; i < strlen(str); i++) {
char c = str[i];
char t[3] = c; //下面str全部t代替
//这里本应该先考虑/* */问题,这里先跳过
if (verifyflag() == LEFT) {
push(S, t);
} else if (verifyflag() == RIGHT) {
if (S.top = S.base) {
printf("错误,右运算符多余");
} else {
SElemtype t1;
pop(stacksize, t1);
if (!matches(t, t1)) {
printf("匹配失败");
return 0;
}
}
}
}
if (S.base != S.top) {
printf("左运算多余,失败");
return 0;
} else {
printf("匹配成功");
return 1;
}
} else {
printf("运算符为空,失败");
return 0;
}
}
//Q2,大数相加问题用的栈链,
当数字超出long long 需要我们用字符串的形式,利用栈去实现大数的相加
//两个加数先从高位到底位依次压入两个栈中,如果钧非空,弹出栈顶元素相加,和存入到oartialSum中,若和有进位
//直接将进位,放到下1位运算,将个位数字压入到结果栈sum中,如果没有进位,直接压入sum;
//如果现在某个加数栈是空的,将另外一个依次弹出栈顶元素与进位相加,压入sum栈,如果最高位还有进位,最后将1
//,压入sum中(就是9999999的情况)。最后两个都空了那就是结果。
linkstack Numtrans(char *str) { //将str以单个字符压入栈中,并且删除空格
linkstack S;
initstacklist(S);
for (int i = 0; i < strlen(str); i++) {
char c = str[i]; //指定索引处的char值
if (c == ' ') {
continue;
} else if ('0' <= c && c <= '9') {
pushstack(S, c);
} else {
printf("有非数字的字符,失败");
return 0;//书上写exit(-1);
}
}
return S;
}
char *ADDbignumber(char *a, char *b) {
linkstack sum;
initstacklist(sum);
linkstack sA = Numtrans(a);
linkstack sB = Numtrans(b);
int partialsum;
bool isCarry = false;
while (sA && sB) { //两个栈链非空
int c1, c2;
popstack(sA, c1);
popstack(sB, c2);
//直接写两个的和
partialsum = c1 - '0' + c2 - '0';
if (isCarry) {
partialsum++;
isCarry = false;
}
if (partialsum > 9) {
partialsum -= 10;
pushstack(sum, partialsum); //个位压入栈
isCarry = true;
} else {
pushstack(sum, partialsum);
}
}
linkstack temp = (sA) ? sA : sB; //temp指向非空的
while (temp) {
int t;
if (isCarry) {
popstack(temp, t);
t = t - '0';
++t;
if (t > 9) {
t -= 10;
pushstack(sum, t);
} else {
pushstack(sum, t);
isCarry = false;
}
} else {
popstack(temp, t - '0');
pushstack(sum, t);
}
}
// 最后考虑特殊的999999
if (isCarry) {
popstack(temp, 1);
isCarry = false;
}
char str[100];
int i;
while (sum) { //栈中元素转化为字符串
int e;
popstack(sum, e);
str[i++] = e + '0'; //整数变成字符
}
str[i] = '\0'; //结果加上结束符
return str;
}
//Q3用栈实现递归
![](https://img-blog.csdnimg.cn/direct/731f69a526b14bcda71f00619e857939.jpeg)
typedef struct {
int n;
double val;
} selemtype;
double p(int n, double x) {
selemtype e;
Sqstack S;
initstack(S);
double f1=1;
double f2=2*x;
if(n==0){
return 1;
}
for(int i=n;i>=2;i--){
e.n=i;
e.val=0;
push(S,e);
}
while(!StackEmpty(S)){
pop(S,e);
e.val=2*x*f2-2*(e.n-1)*f1;
f1=f2;
f2=e.val;
}
return f2;
}