题目描述
语料拓展题:一行文本,其中定义两种特殊语法结构
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);
}
}
}