编程练习:字符串展开

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

给定一个字符串,其中含有括号(大括号,中括号,小括号),括号可以嵌套,且保证括号是配对的,括号前面会有一个数字,要求对字符串进行展开,不带括号,且括号中的内容需要连续出现括号前面数字规定的次数,并且倒序输出;示例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)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    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());
    }
    }
    }
    }

结果

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

感受(总结)

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

最后

此致,敬礼!

~~客官随意,我只是学习怎么配置打赏而已~~