实现迷你解析器把字符串解析成NestInteger类 Mini Parser
为什么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相关推荐
- WPF ---- xmal 解析器没有办法解析类的TypeConverter
xmal 解析器没有办法解析类的TypeConverter.代码如下 页面代码: <Window x:Class="WpfApplication_xmln.Windows.Conver ...
- 解析器 java_Java高性能解析器实现思路及方法学习
当你必须自己实现一个解析器时,你对它的期望会有很多,包括性能良好.灵活.特性丰富.方便使用,以及便于维护等等.说到底,这也是你自己的代码.在本文中,我将为你介绍在Java中实现高性能解析器的一种方式, ...
- python的网页解析器_网页解析器(BeautifulSoup)-- Python
分享一下关于 Python的网页解析器(BeautifulSoup) BeautifulSoup解析器 为了实现解析器,可以选择使用正则表达式.html.parser.BeautifulSoup.lx ...
- java xml解析器_Java XML解析器
java xml解析器 Java XML parser is used to work with xml data. XML is widely used technology to transpor ...
- java sax解析器_Java SAX解析器示例
java sax解析器 SAX Parser in java provides API to parse XML documents. SAX parser is different from DOM ...
- SAXReader解析器--xml字符串文件解析
输入为xml格式字符串 public static void main(String[] args) throws DocumentException {String xml="<?x ...
- python解析器_Python Python解析器
欢迎观临Three太宝小屋- 什么是解析器? 解析器(parser)是指一个程序,通常是编译器的部分,接收输入的顺序源程序指令.交互式联机命令.标记或者一些其它定义的接口. 由于整个Python语言从 ...
- python的网页解析器_Python网页解析器使用实例详解
python 网页解析器 1.常见的python网页解析工具有:re正则匹配.python自带的html.parser模块.第三方库BeautifulSoup(重点学习)以及lxm库. 2.常见网页解 ...
- Spring MVC框架:第二章:视图解析器和@RequestMapping注解使用在类级别及获取原生Servlet API对象
SpringMVC使用细节 第一节 视图解析器 通过HelloWorld程序我们看到了handler方法的返回值表示: 请求处理完成后,请SpringMVC执行一个请求转发.转发的地址就是handle ...
最新文章
- c++11 字符串与int类型的转换
- Python 使用CORS跨域资源共享解决flask服务器跨域问题、浏览器同源策略
- VF02 会计凭证过账时间
- Autofac - 属性注入
- 一行代码值 200 万?雷军公开小米新 Logo 引吐槽
- 62 | 测一测 | 这些软件测试题目,你都掌握了吗?
- DATAGUARD配置错误的解决日志
- android MotionEvent中getX()和getRawX()的区别
- net-tools和ifconfig
- linux家用系统版本,查看linux系统版本
- Threading.Timer用法
- 4.Python标准库_文件管理 (部分os包,shutil包)
- 李航博士:《统计学习方法》第二版上线啦!增加无监督学习!
- 未能加载文件或程序集或它的某一个依赖项。参数不正确
- 百度地图SDK集成定位,卫星地图
- 使用python将图片改为灰度图或黑白图
- Java gateway process exited before sending its port number
- 计算机 蓝牙鼠标卡顿,蓝牙鼠标卡顿不流畅怎么办 最新win10无线鼠标卡顿解决办法...
- 【实战】1213- 点赞动画还可以做得那么飘逸!
- PyTorch安装教程(最简单方法)