博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] Mini Parser 迷你解析器
阅读量:6229 次
发布时间:2019-06-21

本文共 3581 字,大约阅读时间需要 11 分钟。

 

Given a nested list of integers represented as a string, implement a parser to deserialize it.

Each element is either an integer, or a list -- whose elements may also be integers or other lists.

Note: You may assume that the string is well-formed:

  • String is non-empty.
  • String does not contain white spaces.
  • String contains only digits 0-9[- ,].

 

Example 1:

Given s = "324",You should return a NestedInteger object which contains a single integer 324.

 

Example 2:

Given s = "[123,[456,[789]]]",Return a NestedInteger object containing a nested list with 2 elements:1. An integer containing value 123.2. A nested list containing two elements:    i.  An integer containing value 456.    ii. A nested list with one element:         a. An integer containing value 789.

 

这道题让我们实现一个迷你解析器用来把一个字符串解析成NestInteger类,关于这个嵌套链表类的题我们之前做过三道,,,和。应该对这个类并不陌生了,我们可以先用递归来做,思路是,首先判断s是否为空,为空直接返回,不为空的话看首字符是否为'[',不是的话说明s为一个整数,我们直接返回结果。如果首字符是'[',且s长度小于等于2,说明没有内容,直接返回结果。反之如果s长度大于2,我们从i=1开始遍历,我们需要一个变量start来记录某一层的其实位置,用cnt来记录跟其实位置是否为同一深度,cnt=0表示同一深度,由于中间每段都是由逗号隔开,所以当我们判断当cnt为0,且当前字符是逗号或者已经到字符串末尾了,我们把start到当前位置之间的字符串取出来递归调用函数,把返回结果加入res中,然后start更新为i+1。如果遇到'[',计数器cnt自增1,若遇到']',计数器cnt自减1。参见代码如下:

 

解法一:

class Solution {public:    NestedInteger deserialize(string s) {        if (s.empty()) return NestedInteger();        if (s[0] != '[') return NestedInteger(stoi(s));        if (s.size() <= 2) return NestedInteger();        NestedInteger res;        int start = 1, cnt = 0;        for (int i = 1; i < s.size(); ++i) {            if (cnt == 0 && (s[i] == ',' || i == s.size() - 1)) {                res.add(deserialize(s.substr(start, i - start)));                start = i + 1;            } else if (s[i] == '[') ++cnt;            else if (s[i] == ']') --cnt;        }        return res;    }};

 

我们也可以使用迭代的方法来做,这样就需要使用栈来辅助,变量start记录起始位置,我们遍历字符串,如果遇到'[',我们给栈中加上一个空的NestInteger,如果遇到的字符数逗号或者']',如果i>start,那么我们给栈顶元素调用add来新加一个NestInteger,初始化参数传入start到i之间的子字符串转为的整数,然后更新start=i+1,当遇到的']'时,如果此时栈中元素多于1个,那么我们将栈顶元素取出,加入新的栈顶元素中通过调用add函数,参见代码如下:
 
解法二:
class Solution {public:    NestedInteger deserialize(string s) {        if (s.empty()) return NestedInteger();        if (s[0] != '[') return NestedInteger(stoi(s));        stack
st; int start = 1; for (int i = 0; i < s.size(); ++i) { if (s[i] == '[') { st.push(NestedInteger()); start = i + 1; } else if (s[i] == ',' || s[i] == ']') { if (i > start) { st.top().add(NestedInteger(stoi(s.substr(start, i - start)))); } start = i + 1; if (s[i] == ']') { if (st.size() > 1) { NestedInteger t = st.top(); st.pop(); st.top().add(t); } } } } return st.top(); }};

 

还有一种方法是利用C++ STL中的字符串流处理类istringstream,我们需要对几个函数有些了解,比如clear()是重置字符流中的字符串,get()是获得下一个字符,peek()是返回首字符,>>num是读取出合法的整数,如果无法读取出整数,需要调用clear()来重置字符串,否则调用get()会出错。思路跟上面的递归解法相同,参见代码如下:

 

解法三:

class Solution {public:    NestedInteger deserialize(string s) {        istringstream in(s);        return deserialize(in);    }    NestedInteger deserialize(istringstream& in) {        int num;        if (in >> num) return NestedInteger(num);        in.clear();        in.get();        NestedInteger list;        while (in.peek() != ']') {            list.add(deserialize(in));            if (in.peek() == ',') {                in.get();            }        }        in.get();        return list;    }};

 

类似题目:

 

参考资料:

 

转载地址:http://kbxna.baihongyu.com/

你可能感兴趣的文章
关于继承Fragment后重写构造方法而产生的错误
查看>>
2017-5-7 账号激活 权限设置 销售 仓库 财务三大模块
查看>>
datepicker插件的使用
查看>>
用户定义的变量+HTTP Cookie 管理器组合实现接口关联+问题处理
查看>>
linux中查找文件中的内容
查看>>
【C#学习笔记】调用C++生成的DLL
查看>>
Java:类与继承
查看>>
jQuery带tab切换搜索框样式代码
查看>>
jquery如何获得页面元素的坐标值
查看>>
《程序是怎样跑起来的》读书笔记——第六章 亲自尝试压缩数据
查看>>
poj1189
查看>>
AIM Tech Round 4 (Div. 2)
查看>>
JMeter介绍(一)
查看>>
自己实现字符串转整数(不使用JDK的字符串转整数的方法)
查看>>
虚拟化知识点
查看>>
tp的路由器功能1
查看>>
Android屏幕适配笔记
查看>>
deepin安装tftp服务器_远程批量自动安装中标麒麟操作系统的方法
查看>>
igmpproxy_Openwrt与IPTV之一----igmpproxy
查看>>
mysqlnavicat数据库备份与恢复_navicat如何实现mysql备份与恢复
查看>>