编程练习-字符串展开

题目来源:华为实习笔试题

给定一个字符串,其中含有括号(大括号,中括号,小括号),括号可以嵌套,且保证括号是配对的,括号前面会有一个数字,要求对字符串进行展开,不带括号,且括号中的内容需要连续出现括号前面数字规定的次数,并且倒序输出;示例abc3{A},输出结果: AAAcba

分析

(当时内心活动[废话])这是三道题中的第二题,当我看到倒序输出时,毫无疑问这需要用到栈,回想起了之前本科学到的中缀表达式求值。好吧看似一切很顺利,突然发现,括号嵌套,mb,我居然在这个地方陷进去了,所以做了第三题,示例通过率只有45%,再回来做这一题,一直想着两个栈外加一个队列去实现,好吧,恶性循环。最后居然没做出来,更可恨的是,提交了之后,猛然发现自己好蠢啊!

其实两个栈就可以了,一个用作最后的结果栈tack_res,一个用作临时栈stack_temp,用来进行括号中间串的临时存储。
具体步骤:

  1. 循环遍历原始串,如果当前字符不是右括号}、]、),将其push到结果栈stack_res中,否则转2
  2. 将结果栈中的字符依次pop,判断是否是左括号{、[、(,如果是则转3,否者将字符push到临时栈stack_temp中。
  3. 取结果栈stack_res栈顶元素,这个字符一定是括号前面的数字字符n,表示需要将临时栈stack_temp中的内容重复n次。
  4. 将临时栈中的字符拼凑成字符,并借助StringBuilder拼凑n次。
  5. 将拼凑出的字符串依次将字符push到结果栈stack_res中,回到1
    *流程

实现(java)

package sx20190410;
import java.util.*;
/**
 * @ClassName: StringExtendWithKuoHao
 * @Author: fanjiajia
 * @Date: 2019/4/10 下午8:29
 * @Version: 1.0
 * @Description:
 */
public class StringExtendWithKuoHao {

    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {

        List<Character> list = new LinkedList<Character>(){
            {
                add('{');
                add('[');
                add('(');
                add(')');
                add(']');
                add('}');

            }
        };
        List<Character> list_left = new LinkedList<Character>(){
            {
                add('{');
                add('[');
                add('(');
            }
        };
        List<Character> list_right = new LinkedList<Character>(){
            {
                add(')');
                add(']');
                add('}');

            }
        };
        while (scanner.hasNext()) {

            String str = scanner.next(); // 原始字符串
            Stack<Character> stack_res = new Stack<>();
            Stack<Character> stack_temp = new Stack<>();

            for (int i = 0; i < str.length(); i++) {

                if (!list_right.contains(str.charAt(i))) { // 不是右边的
                    stack_res.push(str.charAt(i));
                }else {
                    // 是右边的,消解
                    Character character;
                    while (!list_left.contains((character = stack_res.pop()))) {
                        // 弹出的不是左边括号也就是字符,加入临时栈
                        stack_temp.push(character);
                    }
                    // character是左边括号
                    int n = Integer.valueOf(String.valueOf(stack_res.pop()));
                    String temp = "";
                    StringBuilder sb = new StringBuilder();
                    while (stack_temp.size() > 0) {
                        temp += stack_temp.pop();
                    }
                    for (int j = 0; j < n; j++) {
                        sb.append(temp);
                    }
                    temp = sb.toString();
                    for (int k = 0; k < temp.length(); k++) {
                        stack_res.push(temp.charAt(k));
                    }
                }
            }
            while (stack_res.size() > 0) {
                System.out.print(stack_res.pop());
            }
        }
    }
}

结果

abc3{as2[sd]sd3(we)2{s}4{svf}}
fvsfvsfvsfvsssewewewdsdsdssafvsfvsfvsfvsssewewewdsdsdssafvsfvsfvsfvsssewewewdsdsdssacba

感受(总结)

  • 得多练啊,基础知识啊,队列的使用都不会,气人不气人!
  • 平时不要只做代码搬运工啊,int n = Integer.valueOf('2'); 得到的结果不是2,是50啊(这里是字符2,不是字符串2);
  • scanner.next()遇到空格会结束啊,笨蛋;
  • 提前做好准备工作啊,建好工程,做好准备,像什么数组打印之类的。
  • 实在做不出来,要学会分,通过多少测试用例应该是有分的吧!

最后

此致,敬礼!

原文地址:https://www.cnblogs.com/numen-fan/p/10692072.html