java字符串处理例题

题目描述

语料拓展题:一行文本,其中定义两种特殊语法结构
1. "[一|二]",表示当前位置可选『一』或『二』或空
2. "(一|二)",表示当前位置可选『一』或『二』
两种语法不可嵌套,即不存在[(一|二)|三]这种语法。

给定一行文本,请输出它所有可能的普通文本的排列组合。

举例:我要去[一|二]的地方吃(三|四)可以吗?
可能的展开包括
1. 我要去一的地方吃三可以吗?
2. 我要去一的地方吃四可以吗?
3. 我要去二的地方吃三可以吗?
4. 我要去二的地方吃四可以吗?
5. 我要去的地方吃三可以吗?
6. 我要去的地方吃四可以吗?

解题思路

定义一个内部类,记录所有带替换位置以及待替换的值,使用回溯法将所有可能的结果输出即可

代码

public class Solution1 {

    // 定义一个内部类,存所有待替换的数据
    public class TmpPosition {
        // 开始位置
        public int stpos;
        // 结束位置
        public int edpos;
        // 类型
        public int type;
        // 待替换字符集
        public List<String> strlist = new ArrayList<>();

        public void getlist(String str){
            if(str.charAt(0)=='('){
                type = 0;
            }
            if(str.charAt(0)=='['){
                type = 1;
            }

            // 先将括号内容提取出来
            String content = str.substring(1, str.length()-1);
            // 然后再将可选内容分割
            String[] contents = content.split("\\|");
            for(int i=0; i<contents.length; i++){
                strlist.add(contents[i]);
            }
            if(this.type == 1){
                strlist.add("");
            }
        }

        // 构造函数
        public TmpPosition(int stpos, int edpos, String str){
            this.stpos = stpos;
            this.edpos = edpos;
            getlist(str);
        }

    }

    List<String> result = new ArrayList<>();

    public static void main(String[] args) {
        //String s = "我要去[一|二]的地方吃(三|四)可以吗?";
        String s = "我要去[一|二]的地方吃(三|四)可以吗?(五|六)会更好吗[七|八]?(九|十)更好啊";
        Solution1 solution1 = new Solution1();
        solution1.getResult(s);
        solution1.print();
    }

    // 打印最后结果
    public void print(){
        for(int i=0; i<result.size(); i++){
            System.out.println(result.get(i));
        }
    }

    public void getResult(String s){
        List<TmpPosition> poslist = new ArrayList<>();
        // 解析语料,将所有的可变结构都封装
        for(int i=0; i<s.length(); i++){
            if(s.charAt(i)=='(' || s.charAt(i)=='['){
                int st = i;
                while(s.charAt(i)!=')' && s.charAt(i)!=']') i++;
                int ed = i;
                poslist.add(new TmpPosition(st, ed, s.substring(st, ed+1)));
            }
        }

        // 根据封装的可变信息组装成最后的结果
        assemble(poslist, s, s.length(),0);
    }

    // 其中s是当前层的临时字符串,len用来计算偏移量,k表示当前应该替换第k个位置
    public void assemble(List<TmpPosition> poslist, String s, int len,int k){
        if(k == poslist.size()){
            result.add(s);
            return;
        }
        int offset = len-s.length();
        // 这里面进行替换
        TmpPosition pos = poslist.get(k);
        String s1 = s.substring(0, pos.stpos-offset);
        String s2 = s.substring(pos.edpos-offset+1);
        for(int j=0; j<pos.strlist.size(); j++){
            StringBuilder sb = new StringBuilder();
            sb.append(s1);
            sb.append(pos.strlist.get(j));
            sb.append(s2);
            assemble(poslist, sb.toString(), len,k+1);
        }
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值