栈的简单应用

01_逆序输出

//十进制数n到banse进制的转换(递归版)
void convert(stack<char>& S,__int64_t n,int base){
    static char digit[] = {
            '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
    };
    if(0<n){  //在尚有余数之前,不断
        S.push(digit[n % base]);
        convert(S,n / base ,base);  //通过递归得到最有最高位
    }
}
//迭代版
void convert2(stack<char>& S,__int64_t n,int base){
    static char digit[] = {
            '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
    };
    while(n > 0){
        int remainder = (int)(n % base);
        S.push(digit[remainder]); //余数入栈
        n /= base; //你更新为其对base的除商
    }
}

02_嵌套循环

02_01 栈混洗

  • 这里的栈pop()操作会删除并返回栈顶元素,与c++中的stack标准库不同
  • 栈混洗(stack permutation):有三个栈A,B,S.其中A含有n个元素,B和S初始化为空,只允许通过S.push(A.pop())弹出栈A的顶元素并压入栈S中,或通过B.push(S.pop())弹出S的栈顶元素并压入栈B中
  • 由n次push和n次pop构成的任何操作序列,只要满足”任意前缀中的push不少于pop”限制,则该序列必然对应于某个栈混洗

02_02 括号匹配

递归版采用的是分治法,但是最坏情况时间复杂度为O(N²)

//括号匹配算法(递归版)
void trim(const char exp[],int& lo,int& hi){ //删除表达式exp[lo,hi]不含括号的最长前缀,后缀
    while((lo <= hi) && (exp[lo] != '(') && (exp[lo] != ')'))
        lo++;
    while((lo <= hi) && (exp[hi] != '(') && (exp[hi] != ')'))
        hi--;
}

int divide(const char exp[], int lo, int hi){
    int mi = lo,crc = 1;  //crc为[lo,mi]范围内左右括号数目之差
    while((0 < crc) && (++mi < hi)) {//逐个检查各字符,直到左右括号数目相等,或者越界
        if(exp[mi] == ')')
            crc--;
        if(exp[mi] == '(')
            crc++;
    }
    return mi; //若mi <= hi,合法切分点;否则,意味着局部不可能匹配
}
//检查表达式[lo,hi]是否括号匹配(递归版)
bool paren(const char exp[],int lo,int hi){
    trim(exp,lo,hi);
    if(lo>hi) return true;
    if(exp[lo] != '(')
        return false;  //首字符不是左括号肯定不匹配
    if(exp[hi] != ')')
        return false;
    int mi = divide(exp,lo,hi); //确定适当的切分点
    if(mi >hi) return false; //切分点不合法
    return paren(exp,lo+1,mi-1) && paren(exp,mi+1,lo); //分别检查左右子表达式
}

//括号匹配算法(迭代版)
bool paren2(const char exp[],int lo, int hi) {//可兼顾三种括号
    stack<char> S;//记录已发现,但未匹配的左括号
    for (int i = 0; exp[i]; ++i) { //逐一检查当前字符
        switch (exp[i]) { //左括号直接进栈,右括号若与栈顶失配,则返回false;
            case '(' :
            case '{':
            case '[' :
                S.push(exp[i]);
                break;
            case ')' :
                if ((S.empty()) || ('(' != S.top()))
                    return false;
                S.pop();
                break;
            case '}' :
                if ((S.empty()) || ('{' != S.top()))
                    return false;
                S.pop();
                break;
            case ']' :
                if ((S.empty()) || ('[' != S.top()))
                    return false;
                S.pop();
                break;
            default:
                break; //非括号字符一律忽略
        }
    }
    return S.empty(); //栈空则匹配
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值