zoukankan      html  css  js  c++  java
  • 【小白刷题之路Day28】leetcode394. 字符串解码(括号匹配)

    给定一个经过编码的字符串,返回它解码后的字符串。

    编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

    你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

    此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

    示例:

    s = "3[a]2[bc]", 返回 "aaabcbc".
    s = "3[a2[c]]", 返回 "accaccacc".
    s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/decode-string
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    第一次提交代码:

    class Solution {
    public:
        string decodeString(string s) {
            stack<char> stk;
            string res;
            int i=0;
            
            while (i<s.size()){
                if (s[i] == '['){
                    ++i;
                    
                    while(s[i] != ']'){
                        stk.push(s[i]);
                        ++i;
                    }
                    
                    string tmp;
                    while (stk.top() != '['){
                        tmp = tmp.insert(0, 1, stk.pop());
                    }
                
                    int n = int(stk.pop());
                    for (int j=0; j<n; ++j)
                        res = res + tmp;
                    continue;
                }
                
                if (s[i]>='0' && s[i]<='9'){
                    stk.push(s[i]);
                    ++i;
                    continue;
                }
                    
                res = res + s[i];        
            }
            
            return res;        
        }
    };

    问题1 对模板不熟悉,肯定有不少错误

    问题2 对于嵌套情况没有处理,逻辑上有错误。

    关键还是对C++模板编程不熟,丧失了继续思考的动力,开始看别人的AC代码

    参考@YouLookDeliciousC代码,提交自己代码:

    class Solution {
    public:
        string decodeString(string s) {
            stack<string> str_stack;
            stack<int>  num_stack;
            string tmp;
            int i=0, count = 0;;
            
            while (i<s.size()){
                if (s[i]>='0' && s[i]<='9'){
                    count = count * 10 + (s[i]-'0');
                    ++i;
                    continue;
                }
                
                if (s[i] == '['){
                    num_stack.push(count);
                    count = 0;
                    
                    //str_stack.top() = str_stack.top() + tmp;
                    str_stack.push(tmp);
                    tmp = "";
                    
                    ++i;
                    continue;               
                }
                
                if (s[i] == ']'){
                    for (int j=0; j<num_stack.top(); ++j){
                        str_stack.top() = str_stack.top() + tmp;
                    }
                    tmp = str_stack.top();
                    
                    num_stack.pop();
                    str_stack.pop();                
                    
                    ++i;
                    continue;
                }
                    
                tmp = tmp + s[i];
                ++i;        
            }
            
            return tmp;        
        }
    };

    通过之前,有一个bug:

    if (s[i]>='0' && s[i]<='9'){
       count = count * 10 + int(s[i]);

    可能是python写多了,导致这样的语法,调试结果出来一大堆“aaaaaaa……”,用vs2012调试后发现“3”变为了51,原来是吧‘3’的asc码直接转化。

    while-continue 代码很冗杂,再次对比@YouLookDeliciousC代码后改用for循环控制。

    class Solution {
    public:
        string decodeString(string s) {
            stack<string> str_stack;
            stack<int>  num_stack;
            string tmp;
            int count = 0;
            
            for (int i=0; i<s.size(); ++i){
                if (s[i]>='0' && s[i]<='9'){
                    count = count * 10 + (s[i]-'0');
                }
                else if (s[i] == '['){
                    num_stack.push(count);
                    str_stack.push(tmp);
                    
                    count = 0;                
                    tmp = "";               
                }
                else if (s[i] == ']'){
                    for (int j=0; j<num_stack.top(); ++j){
                        str_stack.top() = str_stack.top() + tmp;
                    }
                    tmp = str_stack.top();
                    
                    num_stack.pop();
                    str_stack.pop();
                }
                else
                    tmp = tmp + s[i];
            }
            
            return tmp;        
        }
    };
    // 我认为这个代码已经精简到了简无可简。

    因为不知道字符是不是全为字母,所以if-else放在最后。

    总结:

    1、本题属于数据结构栈的经典题、基本题;

    2、收获:

    • char型字符转int:
    int count = 0;
    for (int i=0; i<string.size(); ++i)
        if (s[i]>=0 && s[i]<=9)
            count = count * 10 + (s[i] - '0');

    搜了一下库函数操作讲解很多,有机会接着看;

    • C++ STL中stack的使用

    stack<string> str_stack;

    stack.push()

    stack.pop();  注意stack.pop()不返回任何值。

    stack.top()

  • 相关阅读:
    IPv6基础介绍
    SNMP(Simple Network Mnagement Protocol)——简单网络管理协议详解
    GRE(Generic Routing Encapsulation)——通用路由封装协议详解
    NAT(Network Address Translation)网络地址转换详解
    PPPoE(Point to Point Protocol over Ethernet)——以太网上的点对点协议详解
    链路聚合详解——Link Aggregation
    MongoDB快速copy笔记
    MongoDB导入导出和踩过的坑
    Linux离线安装RabbitMQ
    VSCode 开发、运行和调试
  • 原文地址:https://www.cnblogs.com/ACStrive/p/11599709.html
Copyright © 2011-2022 走看看