思路:
同leetcode20有效的括号,如果有左标签,则把右标签加入栈,便于匹配。
同时需要注意使用count调整空格的多少,加入左标签,意味着要向右移动;右标签匹配成功要向左移动。
测试用例:
xml格式化
输入:<a><b></b><cc>ccc</cc></a>
输出:
<a>
<b></b>
<cc>
ccc
</cc>
</a>
代码:
public void xmlParse(String[] str, List<String> res){
Stack<String> stack=new Stack<>();
int count=0;
for(int index=0;index<str.length;index++){
StringBuilder sb = new StringBuilder();
// 不是标签,是中间的内容
if(str[index].charAt(0)!='<'){
for (int j = 0; j < count; j++) {
sb.append(" ");
}
sb.append(str[index]);
res.add(sb.toString());
}else{
//如果是左标签
if(str[index].charAt(1)!='/'){
// 把左标签转为对应的右标签,便于配对比较
String right = toRight(str[index]);
stack.push(right);
for (int j = 0; j < count; j++) {
sb.append(" ");
}
sb.append(str[index]);
res.add(sb.toString());
// 加入左标签则右移
count++;
}
else{//如果是闭合标签
if(stack.peek().equals(str[index])){
stack.pop();
// 左右标签到齐则左移
count--;
if(str[index].equals(toRight(str[index-1]))){
// 左右标签中间没有内容,直接合并左右标签
res.set(res.size()-1,res.get(res.size()-1)+str[index]);
} else{
// 有内容
for (int j = 0; j < count; j++) {
sb.append(" ");
}
sb.append(str[index]);
res.add(sb.toString());
}
}else{
System.out.println("异常");
}
}
}
}
}
public String toRight(String left){
StringBuilder sb = new StringBuilder();
sb.append(left.charAt(0)).append("/");
for (int i = 1; i < left.length(); i++) {
sb.append(left.charAt(i));
}
return sb.toString();
}
测试代码:
String[] str = {"<a>","aa","<b>","</b>","</a>"};
ArrayList<String> res=new ArrayList<>();
new ParseXml().xmlParse(str,res);
for (int i = 0; i < res.size(); i++) {
System.out.println(res.get(i));
}
来源:
题目来源 字节面经