LeetCode刷题总结(C语言版)_栈队列类

编程总结

每每刷完一道题后,其思想和精妙之处没有地方记录,本篇博客用以记录刷题过程中的遇到的算法和技巧
020)有效括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串

思路:将字符串都判断如果是左括号(’(’,’[’,’{’,’(’)都进行入栈,遇到其他括号符号则:1)取出栈顶元素,2)同时将栈顶元素的match括号匹配上,3)然后Pop栈顶元素和match元素进行比对,如果一致继续循环判断,否则退出,直到遍历完所有的字符串长度。


typedef char DataType;
typedef struct node{
    DataType data;
    struct node *next;
} Stack;

Stack* CreateStack();               //创建栈
void StackEmpty(Stack* );           //清空栈
void DestoryStack(Stack*);          //撤销(删除)栈
int IsEmpty(Stack*);                //判空
int PushStack(Stack*, DataType);    //入栈
int PopStack(Stack*);               //出栈
DataType GetTopElement(Stack*);     //取栈顶元素

#define TRUE_T    1
#define FALSE_T   0

bool isValid(char *s) {
    int i = 0;
    Stack *stack_tmp;
    char c = 0;
    char match = 0;
    int length = strlen(s);

    stack_tmp = CreateStack();

    //非成对出现直接return FALSE
    if (length % 2 == 1 ) {
        return FALSE_T;
    }
    //“”,输入空字符串,要返回TRUE
    if (length == 0 ) {
        return TRUE_T;
    }

    for (i = 0; i < length; i++) {
        if (s[i] == '(' || s[i] == '[' || s[i] == '{') {
            PushStack(stack_tmp, s[i]);
        } else {
            if (IsEmpty(stack_tmp)) {
                DestoryStack(stack_tmp);
                return FALSE_T;
            }
            //取出栈顶元素
            c = GetTopElement(stack_tmp);
            PopStack(stack_tmp);

            if (s[i] == ')') {
                match = '(';
            } else if (s[i] == ']') {
                match = '[';
            } else {
               if (s[i] != '}') {
                   DestoryStack(stack_tmp);
                   return FALSE_T;
                }
                match = '{';
            } 

            if (c != match) {
                DestoryStack(stack_tmp);
                return FALSE_T;
            }
        }
    }

    //第一个条件是判断:成对出现"((" ,直接跳过了match判断的操作
    //第二个条件是判断栈如果是非空的,栈里面还有符号,也要返回FALSE
    if (match  == 0 || IsEmpty(stack_tmp) == 0) {
        return FALSE_T;
    }

    DestoryStack(stack_tmp);
    return TRUE_T;
    
}

int main()
{
    int n;
    char *str = "(()(";
    printf("isValid is %d", isValid(str));

    return 0;
}

//创建栈,此时栈中没有任何元素
Stack *CreateStack()
{
    Stack *stack = (Stack *)malloc(sizeof(Stack));

    if (NULL != stack) {
       stack->next = NULL;
       return stack;
    }
    //printf("out of place.\n");

    return NULL;
}
 
//清空栈
void StackEmpty(Stack *stack)
{
    while (!IsEmpty(stack)) {
        PopStack(stack);
    }

}
 
//撤销栈
void DestoryStack(Stack *stack)
{
    free(stack);
    //exit(0);
}
 
int IsEmpty(Stack *stack)
{
    return (stack->next == NULL);
}
 
//入栈,成功返回1,失败返回0, 把元素 data 存入 栈 stack 中
int PushStack(Stack *stack, DataType data)
{
    Stack *newst = (Stack *)malloc(sizeof(Stack));
    if (NULL != newst) {
        newst->data = data;
        newst->next = stack->next;  //s->next = NULL;
        stack->next = newst;
        return 1;
    }

    return 0;
}
 
/*
    出栈,成功返回1,失败返回0,出栈不取出元素值,只是删除栈顶元素。
    如出栈要实现,取出元素值,并释放空间,可结合取栈顶元素函数做修改,这里不再给出。
 */
int PopStack(Stack *stack)
{
    Stack *tmpst;
    if (!IsEmpty(stack)) {
        tmpst = stack->next;
        stack->next = tmpst->next;
        free(tmpst);
        return 1;
    }

    return 0;
}
 
//取栈顶元素,仅取出栈顶元素的值,取出之后,该元素,任然存在栈中。成功返回元素值,失败输出提示信息,并返回 -1
DataType GetTopElement(Stack *stack)
{
    if (!IsEmpty(stack)) {
        return stack->next->data;
    }

    return -1;
}

224)基本计算器
实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格
一个运算符栈opors,一个运算数栈opands。

括号内的计算优先级最高。

碰到’(‘,’(‘入opors栈。

碰到’)’,opors栈中栈顶到’(‘的运算符都要计算出来。 这表示括号内的表达式结束了,然后, ‘(‘ 出栈。

碰到’+”-‘, opors栈中栈顶到’(‘的运算符都要计算出来。 这是左结合性导致的。然后 ‘+”-‘ 入栈。

碰到数字,提取出整数,然后入opands栈。

#include <iostream>
#include <stack>
#include <cctype>
using namespace std;

class Solution {
private:
    stack<int> num;
    stack<char> op;
    int pri(char a){
        switch(a){
        case '+': return 1;
        case '-': return 1;
        case '*': return 2;
        case '/': return 2;
        case '(': return 3;
        default: return -1;
        }
    }
    void cal(){
        int b=num.top();num.pop();
        int a=num.top();num.pop();
        switch(op.top()){
        case '+':num.push(a+b);break;
        case '-':num.push(a-b);break;
        case '*':num.push(a*b);break;
        case '/':num.push(a/b);break;
        }
        op.pop();
    }
public:
    int calculate(string s) {
        string ss;
        for(int i=0;i<(int)s.size();i++){
            if(isdigit(s[i]))
                ss+=s[i];
            else if(s[i]==' ') continue; //碰到空格
            else{
            	//碰到数字,提取出整数,然后入opands栈
                if(!ss.empty()){
                    num.push(stoi(ss));
                    ss.clear();
                }
                //碰到'(','('入opors栈;碰到当前元素优先级高于栈顶元素,入栈
                if(op.empty()||s[i]=='('||pri(op.top())<pri(s[i]) )
                    op.push(s[i]);
                //碰到’)’,opors栈中栈顶到'(‘的运算符都要计算出来; 这表示括号内的表达式结束了,然后, ‘(‘ 出栈。
                else if(s[i]==')'){
                    while(op.top()!='(') cal();
                    op.pop();
                }//只要满足当前元素优先级高于栈顶元素,都进行计算,直到遇到更高优先级元素,完成计算后,让它进栈
                else{
                    while(!op.empty()&&pri(op.top())<=pri(s[i])) cal();
                    op.push(s[i]);
                }
            }
        }
        if(!ss.empty()) num.push(stoi(ss));
        while(!op.empty()) cal();
        return num.top();
    }
};

int main(){
    Solution s;
    cout<<s.calculate("(1+(4+5+2)-3)+(6+8)")<<endl;
}
发布了14 篇原创文章 · 获赞 31 · 访问量 6万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览