import java.io.*;
import java.util.*;
/**
* 过滤组合字符串
* 7关联u/v,8关联x/w,输入一个字符串例如78和一个屏蔽字符串ux
* 那么78可以组成多个字符串例如ux/uw/vx/vw,
* 过滤这些完全包含屏蔽字符串的每一个字符的字符串,然后输出剩下的字符串
* numCharMap.put('0', "abc");
* numCharMap.put('1', "def");
* numCharMap.put('2', "ghi");
* numCharMap.put('3', "jkl");
* numCharMap.put('4', "mno");
* numCharMap.put('5', "pqr");
* numCharMap.put('6', "st");
* numCharMap.put('7', "uv");
* numCharMap.put('8', "wx");
* numCharMap.put('9', "yz");
*/
public class FilterCombinationString {
/*
78
ux
------------------------
uw vx vw
*/
/**
* 输入数字字符
*/
public static String numStr;
/**
* 数字字符对应字符数组
*/
public static char[] numChars;
/**
* 屏蔽字符
*/
public static String blockStr;
/**
* 数字字符对照表
*/
public static Map<Character, String> numCharMap = new HashMap<>();
/**
* 结果字符串列表
*/
public static List<String> resStrList = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
//读取数字字符串
numStr = in.readLine();
//将数字字符串转换成字符数组
numChars = numStr.toCharArray();
//屏蔽字符串
blockStr = in.readLine();
//初始化数字与字符的映射关系
numCharMap.put('0', "abc");
numCharMap.put('1', "def");
numCharMap.put('2', "ghi");
numCharMap.put('3', "jkl");
numCharMap.put('4', "mno");
numCharMap.put('5', "pqr");
numCharMap.put('6', "st");
numCharMap.put('7', "uv");
numCharMap.put('8', "wx");
numCharMap.put('9', "yz");
// 使用深度优先搜索生成所有可能的字符串组合
dfs(new ArrayList<>(), 0);
StringBuilder sb = new StringBuilder();
for (String resStr : resStrList) {
// 过滤掉包含屏蔽字符串中所有字符的字符串
if (canShow(resStr)) {
sb.append(resStr).append(" ");
}
}
sb.deleteCharAt(sb.length() - 1);
out.println(sb.toString());
out.flush();
in.close();
out.close();
}
/**
* 深度优先搜索
* @param path 字符路径
* @param index 索引
*/
public static void dfs(List<Character> path, int index) {
//索引达到数字字符长度,拼接该组合下的结果字符,存入结果列表后返回
if (index == numStr.length()) {
StringBuilder sb = new StringBuilder();
for (char c:path) {
sb.append(c);
}
resStrList.add(sb.toString());
return;
}
// 从map中获取当前索引指向数字字符所对应的字符串,并将其转成字符数组
char[] chars = numCharMap.get(numChars[index]).toCharArray();
// 将字符数组中的字符依次加入路径列表,递归后恢复原来位置
for (char c : chars) {
path.add(c);
dfs(path, index + 1);
path.remove(path.size() - 1);
}
}
/**
* 检查str是否包含blockStr中的所有字符
* 不能用str.contains(blockStr),因为字符顺序可能不一致
* @param str 待验证的结果字符串
* @return 是否可以输出(不需要屏蔽)
*/
private static boolean canShow(String str) {
Set<Character> strSet = new HashSet<>();
for (int i = 0; i < str.length(); i++) {
strSet.add(str.charAt(i));
}
Set<Character> blockSet = new HashSet<>();
for (int i = 0; i < blockStr.length(); i++) {
blockSet.add(blockStr.charAt(i));
}
for (Character c : blockSet) {
if (!strSet.contains(c)) {
return true;
}
}
return false;
}
}