Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 给定的整数到字符的映射查找给定整数的所有可能的字符组合_Java_Algorithm - Fatal编程技术网

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"));
}