为什么80%的码农都做不了架构师?>>>   

问题:

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类。

对输入的每个字符进行判断 
数字: 用l保存开始 用i保存数字最后一位的下一位 用substring进行裁剪 
字符‘[’ :遇到 [ 时将上一级的NestedInteger保存入栈 进行下一步操作 
字符’]’:判断是否需要将数字加入当前NestedInteger,然后将上一级NestedInteger弹出 将这一级的NestedInteger加入到上一级的NestedInteger中去 
字符’,’判断是否要将数字加入当前NestedInteger

① 递归方法解决。首先判断s是否为空,为空直接返回,不为空的话看首字符是否为'[',不是的话说明s为一个整数,我们直接返回结果。如果首字符是'[',且s长度小于等于2,说明没有内容,直接返回结果。反之如果s长度大于2,我们从i=1开始遍历,我们需要一个变量start来记录某一层的起始位置,用count来记录跟起始位置是否为同一深度,count=0表示同一深度,由于中间每段都是由逗号隔开,所以当我们判断当count为0,且当前字符是逗号或者已经到字符串末尾了,我们把start到当前位置之间的字符串取出来递归调用函数,把返回结果加入res中,然后start更新为i+1。如果遇到'[',计数器count自增1,若遇到']',计数器count自减1。

class Solution { //17ms
    public NestedInteger deserialize(String s) {
        NestedInteger res = new NestedInteger();
        if (s == null || s.length() == 0) return res;
        if (s.charAt(0) != '[') {
            res.setInteger(Integer.parseInt(s));
        } else if (s.length() > 2) {
            int start = 1, count = 0;
            for (int i = 1; i < s.length(); i++) {
                char c = s.charAt(i);
                if (count == 0 && (c == ',' || i == s.length() - 1)) {
                    res.add(deserialize(s.substring(start, i)));
                    start = i + 1;
                }
                else if (c == '[') count++;
                else if (c == ']') count--;
            }
        }
        return res;
    }
}

② 非递归方法,用栈维护一个包含关系。

/**
* // This is the interface that allows for creating nested lists.
* // You should not implement it, or speculate about its implementation
* public interface NestedInteger {
*     // Constructor initializes an empty nested list.
*     public NestedInteger();
*
*     // Constructor initializes a single integer.
*     public NestedInteger(int value);
*
*     // @return true if this NestedInteger holds a single integer, rather than a nested list.
*     public boolean isInteger();
*
*     // @return the single integer that this NestedInteger holds, if it holds a single integer
*     // Return null if this NestedInteger holds a nested list
*     public Integer getInteger();
*
*     // Set this NestedInteger to hold a single integer.
*     public void setInteger(int value);
*
*     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
*     public void add(NestedInteger ni);
*
*     // @return the nested list that this NestedInteger holds, if it holds a nested list
*     // Return null if this NestedInteger holds a single integer
*     public List<NestedInteger> getList();
* }
*/

class Solution{ //23ms
    public NestedInteger deserialize(String s) {
        Stack<NestedInteger> stack = new Stack<NestedInteger>();
        String tokenNum = "";
        for (char c : s.toCharArray()) {
            switch (c) {
                case '['://[代表一个list
                    stack.push(new NestedInteger());
                    break;
                case ']'://list结尾
                    if (!tokenNum.equals(""))//前面token为数字 
                        stack.peek().add(new NestedInteger(Integer.parseInt(tokenNum)));//将数字加入到本层list中
                    NestedInteger ni = stack.pop();//本层list结束
                    tokenNum = "";
                    if (!stack.isEmpty()) {//栈内有更高层次的list
                        stack.peek().add(ni);
                    } else {//栈为空,遍历到字符串结尾
                        return ni;
                    }
                    break;
                case ',':
                    if (!tokenNum.equals("")) //将数字加入到本层list中
                        stack.peek().add(new NestedInteger(Integer.parseInt(tokenNum)));
                    tokenNum = "";
                    break;
                default:
                    tokenNum += c;
            }
        }
        if (!tokenNum.equals(""))//特殊case: 如果字符串只包含数字的情况
            return new NestedInteger(Integer.parseInt(tokenNum));
        return null;
    }
}

③ 在discuss中看到的,使用数组实现栈。。。

class Solution {
    public NestedInteger deserialize(String s) {
        NestedInteger parent = new NestedInteger();
        deserialize(s.toCharArray(), 0, parent);
        return parent.getList().get(0);
    }
    private int deserialize(char[] schar, int i, NestedInteger parent) {
        char c = schar[i++];
        NestedInteger nestedInteger;
        if (c == '[') {
            nestedInteger = new NestedInteger();
            if(schar[i] == ']') {
                i++;
            } else {
                do {
                    i = deserialize(schar, i, nestedInteger);
                } while(schar[i++] != ']');
            }
        } else {
            boolean isNeg = false;
            if (c == '-') {
                isNeg = true;
                c = schar[i++];
            }
            int num = c - '0';
            for (; i < schar.length && (c = schar[i]) >= '0' && c <= '9'; i++) {
                num = num * 10 + c - '0';
            }
            nestedInteger = new NestedInteger(isNeg ? -num : num);
        }
        parent.add(nestedInteger);
        return i;
    }
}

【注】NestedInteger类的简单实现。

class NestedInteger {
    private List<NestedInteger> list;
    private Integer integer;
    public NestedInteger(List<NestedInteger> list){
        this.list = list;
    }
    public void add(NestedInteger nestedInteger) {
        if(this.list != null){
            this.list.add(nestedInteger);
        } else {
            this.list = new ArrayList();
            this.list.add(nestedInteger);
        }
    }
    public void setInteger(int num) {
        this.integer = num;
    }
    public NestedInteger(Integer integer){
        this.integer = integer;
    }
    public NestedInteger() {
        this.list = new ArrayList();
    }
    public boolean isInteger() {
        return integer != null;
    }
    public Integer getInteger() {
        return integer;
    }
    public List<NestedInteger> getList() {
        return list;
    }
    public String printNi(NestedInteger thisNi, StringBuilder sb){
        if(thisNi.isInteger()) {
            sb.append(thisNi.integer);
            sb.append(",");
        }
        sb.append("[");
        for(NestedInteger ni : thisNi.list){
            if(ni.isInteger()) {
                sb.append(ni.integer);
                sb.append(",");
            }
            else {
                printNi(ni, sb);
            }
        }
        sb.append("]");
        return sb.toString();
    }
}

转载于:https://my.oschina.net/liyurong/blog/1596784

实现迷你解析器把字符串解析成NestInteger类 Mini Parser相关推荐

  1. WPF ---- ​xmal 解析器没有办法解析类的TypeConverter

    xmal 解析器没有办法解析类的TypeConverter.代码如下 页面代码: <Window x:Class="WpfApplication_xmln.Windows.Conver ...

  2. 解析器 java_Java高性能解析器实现思路及方法学习

    当你必须自己实现一个解析器时,你对它的期望会有很多,包括性能良好.灵活.特性丰富.方便使用,以及便于维护等等.说到底,这也是你自己的代码.在本文中,我将为你介绍在Java中实现高性能解析器的一种方式, ...

  3. python的网页解析器_网页解析器(BeautifulSoup)-- Python

    分享一下关于 Python的网页解析器(BeautifulSoup) BeautifulSoup解析器 为了实现解析器,可以选择使用正则表达式.html.parser.BeautifulSoup.lx ...

  4. java xml解析器_Java XML解析器

    java xml解析器 Java XML parser is used to work with xml data. XML is widely used technology to transpor ...

  5. java sax解析器_Java SAX解析器示例

    java sax解析器 SAX Parser in java provides API to parse XML documents. SAX parser is different from DOM ...

  6. SAXReader解析器--xml字符串文件解析

    输入为xml格式字符串 public static void main(String[] args) throws DocumentException {String xml="<?x ...

  7. python解析器_Python Python解析器

    欢迎观临Three太宝小屋- 什么是解析器? 解析器(parser)是指一个程序,通常是编译器的部分,接收输入的顺序源程序指令.交互式联机命令.标记或者一些其它定义的接口. 由于整个Python语言从 ...

  8. python的网页解析器_Python网页解析器使用实例详解

    python 网页解析器 1.常见的python网页解析工具有:re正则匹配.python自带的html.parser模块.第三方库BeautifulSoup(重点学习)以及lxm库. 2.常见网页解 ...

  9. Spring MVC框架:第二章:视图解析器和@RequestMapping注解使用在类级别及获取原生Servlet API对象

    SpringMVC使用细节 第一节 视图解析器 通过HelloWorld程序我们看到了handler方法的返回值表示: 请求处理完成后,请SpringMVC执行一个请求转发.转发的地址就是handle ...

最新文章

  1. c++11 字符串与int类型的转换
  2. Python 使用CORS跨域资源共享解决flask服务器跨域问题、浏览器同源策略
  3. VF02 会计凭证过账时间
  4. Autofac - 属性注入
  5. 一行代码值 200 万?雷军公开小米新 Logo 引吐槽
  6. 62 | 测一测 | 这些软件测试题目,你都掌握了吗?
  7. DATAGUARD配置错误的解决日志
  8. android MotionEvent中getX()和getRawX()的区别
  9. net-tools和ifconfig
  10. linux家用系统版本,查看linux系统版本
  11. Threading.Timer用法
  12. 4.Python标准库_文件管理 (部分os包,shutil包)
  13. 李航博士:《统计学习方法》第二版上线啦!增加无监督学习!
  14. 未能加载文件或程序集或它的某一个依赖项。参数不正确
  15. 百度地图SDK集成定位,卫星地图
  16. 使用python将图片改为灰度图或黑白图
  17. Java gateway process exited before sending its port number
  18. 计算机 蓝牙鼠标卡顿,蓝牙鼠标卡顿不流畅怎么办 最新win10无线鼠标卡顿解决办法...
  19. 【实战】1213- 点赞动画还可以做得那么飘逸!
  20. PyTorch安装教程(最简单方法)

热门文章

  1. 如何使用SAP零售系统中的LISTING?
  2. SAP PM 初级系列之27 – SAP系统怎么知道某种类型的维修工单检验批上的检验类型是14?
  3. 那个被捧上天的GPT-3要开始收费了!网友:天价,溜了溜了
  4. 机器学习与数据挖掘有什么异同?
  5. SAP S4HANA系统里的客供件管理
  6. 基于深度学习的文本数据特征提取方法之Glove和FastText
  7. 任正非:华为自己做芯片很难,咬着牙慢慢挺过来了
  8. SAP MM IV中的Duplicated Invoice Check功能的测试
  9. SAP MM MB1C + 523 移动类型的使用
  10. 免费教材丨第58期:机器学习相关汇总资料大放送(中)