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

#define MAXSIZE 100

typedef struct Stack
{
    char *base; //栈底指针
    char *top; //栈顶指针
    int stacksize; //栈可用的最大容量
    int length; //新增：用来判断栈是否为空
}Stack;

//初始化
void InitStack(Stack &p)
{
    p.base = new char[MAXSIZE]; //分配空间
    //todo list 处理 栈顶指针top初始为base
    p.top = p.base;
    //todo list 处理stacksize、length
    p.stacksize = MAXSIZE;
    p.length = 0;
}

#define OK 1
#define ERROR 0
typedef int Status;

//入栈
Status Push(Stack &p, char e)
{
    if(p.top - p.base == p.stacksize) // 栈满
        return ERROR;
    //todo list //将元素e压入栈顶
    *p.top = e;
    //todo list //栈顶指针加1
    p.top++;
    p.length++;
    return OK;
}

//出栈
char Pop(Stack &p)
{
    char e;
    if(p.top == p.base) // 栈空
        return '\0';
    //todo list //栈顶指针减1
    p.top--;
    //todo list //取栈顶元素
    e = *p.top;
    p.length--;
    return e;
}

//1、判断是否为回文串
void Palindrome(Stack &S, char a[])
{
    int i;
    //栈清空
    S.top = S.base;
    S.length = 0;
    for (i = 0; a[i] != '\0'; i++){
        //todo list //for循环 把字符串全部入栈Push()
        Push(S, a[i]);
    }
    for (i = 0; a[i] != '\0'; i++){
        //todo list //for循环 对比串的两端元素，如果Pop(S) != a[i]则表明不是回文,退出
        if(Pop(S) != a[i]){
            printf("----不是回文----\n");
            return;
        }
    }
    if (i == strlen(a))
    {
        printf("------回文------\n");
    }
    else
    {
        printf("----不是回文----\n");
    }
}

//2、括号匹配检验------可参考课本P75
//只讨论由圆括号()和中括号[]组成的括号
void Matching(Stack &S, char ch[])
{
    int flag = 1; //flag初始为1，当 flag = 1时表示匹配成功
    int i=0;
    //栈清空
    S.top = S.base;
    S.length = 0;
    //todo list //while做括号匹配检验：
    while(ch[i] != '\0' && flag){
        //若为左括号，则将其入栈；
        if(ch[i] == '(' || ch[i] == '['){
            Push(S, ch[i]);
        }
        //若为右括号，则与出栈的栈顶元素进行比较，分析是否能够配对（如果不匹配，注意将flag置为0 ）。
        else if(ch[i] == ')' || ch[i] == ']'){
            if(S.length == 0){
                flag = 0;
            }
            else{
                char left = Pop(S);
                if((ch[i] == ')' && left != '(') || (ch[i] == ']' && left != '[')){
                    flag = 0;
                }
            }
        }
        i++;
    }
    if(S.length == 0 && flag ) //栈空且flag = 1时，括号匹配
        printf("-----括号匹配-----\n");
    else
        printf("----括号不匹配----\n");
}

int main()
{
    char a[20], b[20];
    Stack s;
    InitStack(s);
    int choose = -1;
    printf("------------------------------\n");
    printf("1.判断是否是回文字符串\n");
    printf("2.判断括号是否匹配\n");
    printf("0.退出\n");
    printf("------------------------------\n");
    while(choose)
    {
        printf("请输入选项:");
        scanf("%d", &choose);
        switch(choose)
        {
            case 1:
                printf("请输入一个字符串：");
                scanf("%s",a);
                Palindrome(s, a);
                break;
            case 2:
                printf("请输入一个字符串(由圆括号和中括号组成)：");
                scanf("%s",b);
                Matching(s, b);
                break;
            case 0:
                exit(0);
                break;
        }
    }
    return 0;
}
