Java 给定的整数到字符的映射查找给定整数的所有可能的字符组合
我有一个库,其中包含从整数到字符的映射。我还有一个整数格式的字符串。我试图编写一个方法,在解释字符串时返回所有可能的字符组合。例如: 给定以下库Java 给定的整数到字符的映射查找给定整数的所有可能的字符组合,java,algorithm,Java,Algorithm,我有一个库,其中包含从整数到字符的映射。我还有一个整数格式的字符串。我试图编写一个方法,在解释字符串时返回所有可能的字符组合。例如: 给定以下库a=1、b=2、c=3、k=11和字符串“1123”,输出应该是一个包含“aabc”、“kbc”的列表,假设所有给定的数字都可以在库中找到 我目前的解决办法如下: public static ArrayList<String> d(String s) { ArrayList<String> s2 = new ArrayLi
a=1、b=2、c=3、k=11
和字符串“1123”
,输出应该是一个包含“aabc”、“kbc”
的列表,假设所有给定的数字都可以在库中找到
我目前的解决办法如下:
public static ArrayList<String> d(String s) {
ArrayList<String> s2 = new ArrayList<String>();
if (s.length() == 1) {
s2.add(""+library.get(Integer.valueOf(s)));
return s2;
}
for (int i=0; i < s.length(); i++) {
String curr = s.substring(0, i + 1);
if (library.containsKey(Integer.valueOf(curr))){
ArrayList<String> strings = d(s.substring(i + 1));
char c2 = library.get(Integer.valueOf(curr));
for (String tmp : strings){
s2.add(c2 + tmp);
}
}
}
return s2;
}
公共静态数组列表d(字符串s){
ArrayList s2=新的ArrayList();
如果(s.长度()==1){
s2.添加(“+library.get(Integer.valueOf(s)));
返回s2;
}
对于(int i=0;i
有没有更好的方法来解决这个问题?还有,我的解决方案的复杂性是什么?我的假设是O(N^3)时间。您的问题映射到以下语法:
S -> SA | SB | SC | SK | ε
A -> 1
B -> 2
C -> 3
K -> 11
这是一种上下文无关语法,这意味着任何合适的解析器(,)都会在O(n3)时间内将其解析为最坏情况。任何比这更糟糕的事情,你肯定走错了方向
(注意:虽然语法是上下文无关的,但它定义的语言实际上是正则的。增加的复杂性来自于我们生成所有可能的解析树的要求。如果要求只是确定整数在我们的语言中是否是有效的句子,正则表达式
((1)|(2)|(3)|(11))+
就足够了)这个问题让我想起一个据称在谷歌采访中被问到的问题:
编写一个程序,计算建造N高乐高塔的所有不同方法,乐高塔的长度和宽度为1,高度由集合给出(即[1,2,3,4])
在本例中<代码>库<代码>是集合,我们必须考虑一个附加的约束:一个片段必须与文本匹配。
由此,我们可以尝试使用动态规划解决方案来计算可能的“建筑物”数量:公共静态整数NCASE(字符串s)
{
int ncases[]=新的int[s.长度()];
对于(int i=0;i=0)prev=ncases[j-1];
如果(j>=0&&s.substring(j,i+1).equals(mapStr))
ncases[i]+=上一个;
}
}
如果(ncases.长度>0)
返回NCASE[NCASE.length-1];
返回0;
}
此解决方案易于修改,以跟踪每个案例,从而根据您的要求提供一个列表:
private static class Pair<T,L>
{
public Pair(T first, L second) {
this.first = first;
this.second = second;
}
T first;
L second;
}
public static List<String> dynamicd(String s)
{
Pair<Integer,List<String>> ncases[] = new Pair[s.length()];
for(int i = 0; i < s.length(); i++)
{
ncases[i] = new Pair<Integer, List<String>>(0, new ArrayList<String>());
for(Map.Entry<Integer,Character> piece: library.entrySet())
{
String mapStr = piece.getKey().toString();
int j = i+1-mapStr.length();
Pair<Integer, List<String>> prev =
new Pair<Integer, List<String>>(1,new ArrayList<String>());
prev.second.add("");
if(j-1>=0) prev = ncases[j-1];
if(j>= 0 && s.substring(j, i+1).equals(mapStr))
{
ncases[i].first += prev.first;
for(String pcase: prev.second)
ncases[i].second.add(pcase+piece.getValue());
}
}
}
if(ncases.length>0)
return ncases[ncases.length-1].second;
return new ArrayList<>();
}
私有静态类对
{
公共对(T第一,L第二){
this.first=first;
这个秒=秒;
}
T第一;
1秒;
}
公共静态列表动态CD(字符串s)
{
对NCASE[]=新对[s.长度()];
对于(int i=0;i=0)prev=ncases[j-1];
如果(j>=0&&s.substring(j,i+1).equals(mapStr))
{
ncases[i].first+=prev.first;
for(字符串pcase:prev.second)
ncase[i].second.add(pcase+piece.getValue());
}
}
}
如果(ncases.长度>0)
返回ncases[ncases.length-1]。秒;
返回新的ArrayList();
}
如果N=s.length()
和M=library.size()
,这种方法的时间复杂度最差为O(N*M)
以下是代码(这是不言自明的)
公共静态集合所有置换(int num){
TreeNode root=createTree(toArray(num));
收集结果=新建ArrayList();
allLeafNodes(根,结果);
返回结果;
}
私有静态整数[]toArray(int num){
ArrayDeque数组=新的ArrayDeque();
做{
array.push(num%10);
num/=10;
}而(num>0);
返回array.toArray(新整数[0]);
}
私有静态树节点createTree(整数[]整数){
返回doCreateTree(0,“,整数);
}
私有静态TreeNode doCreateTree(int索引、字符串parentString、整数[]整数){
String nodeData=parentString+AlphabetMatcher.match(索引);
TreeNode root=新的TreeNode(nodeData);
if(integers.length!=0){
root.left=doCreateTree(整数[0],节点数据,数组.copyOfRange(整数,1,整数.length));
if(integers.length>1){
int newIndex=整数[0]*10+整数[1];
root.right=doCreateTree(newIndex,nodeData,Arrays.copyOfRange(integers,2,integers.length));
}
}
返回根;
}
私有静态void allLeafNodes(树节点根,收集结果){
if(root!=null){
if(root.right==null&&root.left==null){
结果.添加(根.数据);
}
allLeafNodes(root.left,结果);
allLeafNodes(root.right,结果);
}
}
私有静态类树节点{
私有字符串数据;
私有树节点左;
私有树节点权;
公共树节点(字符串数据){
这个数据=数据;
}
}
私有静态类AlphabetMatcher{
私有静态最终字符串[]字母={“,”a“,”b“,”c“,”d“,”e“,
private static class Pair<T,L>
{
public Pair(T first, L second) {
this.first = first;
this.second = second;
}
T first;
L second;
}
public static List<String> dynamicd(String s)
{
Pair<Integer,List<String>> ncases[] = new Pair[s.length()];
for(int i = 0; i < s.length(); i++)
{
ncases[i] = new Pair<Integer, List<String>>(0, new ArrayList<String>());
for(Map.Entry<Integer,Character> piece: library.entrySet())
{
String mapStr = piece.getKey().toString();
int j = i+1-mapStr.length();
Pair<Integer, List<String>> prev =
new Pair<Integer, List<String>>(1,new ArrayList<String>());
prev.second.add("");
if(j-1>=0) prev = ncases[j-1];
if(j>= 0 && s.substring(j, i+1).equals(mapStr))
{
ncases[i].first += prev.first;
for(String pcase: prev.second)
ncases[i].second.add(pcase+piece.getValue());
}
}
}
if(ncases.length>0)
return ncases[ncases.length-1].second;
return new ArrayList<>();
}
public static Collection<String> allPermutations(int num) {
TreeNode root = createTree(toArray(num));
Collection<String> result = new ArrayList<String>();
allLeafNodes(root, result);
return result;
}
private static Integer[] toArray(int num) {
ArrayDeque<Integer> array = new ArrayDeque<Integer>();
do{
array.push(num % 10);
num /= 10;
} while (num > 0);
return array.toArray(new Integer[0]);
}
private static TreeNode createTree(Integer[] integers) {
return doCreateTree(0, "", integers);
}
private static TreeNode doCreateTree(int index, String parentString, Integer[] integers) {
String nodeData = parentString + AlphabetMatcher.match(index);
TreeNode root = new TreeNode(nodeData);
if (integers.length != 0) {
root.left = doCreateTree(integers[0], nodeData, Arrays.copyOfRange(integers, 1, integers.length));
if (integers.length > 1) {
int newIndex = integers[0]* 10 + integers[1];
root.right = doCreateTree(newIndex, nodeData, Arrays.copyOfRange(integers, 2, integers.length));
}
}
return root;
}
private static void allLeafNodes(TreeNode root, Collection<String> result) {
if (root != null) {
if (root.right == null && root.left ==null) {
result.add(root.data);
}
allLeafNodes(root.left, result);
allLeafNodes(root.right, result);
}
}
private static class TreeNode {
private String data;
private TreeNode left;
private TreeNode right;
public TreeNode(String data) {
this.data = data;
}
}
private static class AlphabetMatcher {
private static final String[] alphabet = {"", "a", "b", "c", "d", "e",
"f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
"s", "t", "u", "v", "w", "x", "v", "z"};
public static String match(int number) {
return alphabet[number];
}
}
@Test
public void allPermutationsTest() {
Collection<String> result = StringUtil.allPermutations(1221);
org.assertj.core.api.Assertions.assertThat(result).hasSize(5).containsAll(Arrays.asList("abba","abu", "ava", "lba", "lu"));
result = StringUtil.allPermutations(10);
org.assertj.core.api.Assertions.assertThat(result).hasSize(2).containsAll(Arrays.asList("a","j"));
}