Algorithm 获取构成给定字符串的所有数组元素的组合

Algorithm 获取构成给定字符串的所有数组元素的组合,algorithm,recursion,Algorithm,Recursion,我被这个面试问题困住了。 给定一个单词S和一个字符串数组a。如何找到可以形成S的元素的所有可能组合。 例如: S = "hotday" A = ["o","ho","h","tday"] 可能的组合是:(“h”+“o”+“tday”)和(“ho”+“tday”) 谢谢您可以遍历A的所有排列,看看哪一个适合。Python示例实现: import itertools S = "hotday" A = ["o","ho","h","tday"] for count in range(len(A)):

我被这个面试问题困住了。 给定一个单词S和一个字符串数组a。如何找到可以形成S的元素的所有可能组合。 例如:

S = "hotday"
A = ["o","ho","h","tday"]
可能的组合是:(“h”+“o”+“tday”)和(“ho”+“tday”)


谢谢

您可以遍历A的所有排列,看看哪一个适合。Python示例实现:

import itertools
S = "hotday"
A = ["o","ho","h","tday"]
for count in range(len(A)):
    for pieces in itertools.permutations(A, count):
        if "".join(pieces) == S:
            print pieces
结果:

('ho', 'tday')
('h', 'o', 'tday')

是的,这是O(N!),但对于您提供的小型
A
,这是可以的。

您可以使用回溯。下面是一些伪代码:

def generateSolutions(unusedWords, usedWords, string, position):
    if position == string.length():
        print(usedWords)
    else:
         for word in unusedWords:
             if word is a prefix of string[position ... s.length() - 1]:
                 generateSolutions(unusedWords - word, usedWords + word, 
                                   string, position + word.length())

generateSolution(words, an empty list, input string, 0)

这个想法非常简单:我们只需选择一个与输入字符串其余部分的前缀匹配的未使用单词,并不断递归地生成所有有效组合(我假设我们只能使用给定单词列表中的每个单词一次)。此解决方案具有指数时间复杂性,但在最坏的情况下不可能做得更好。例如,如果给定的字符串是
abcdef…yz
,单词列表是
[a,b,c,…,z,ab,cd,…,yz]
,那么这样的组合的数量是
2^n/2
,其中
n
是给定字符串的长度。

这是我的java解决方案,它是“ILoveCoding”伪代码的实现:

import java.util.ArrayList;
导入java.util.array;
导入java.util.HashSet;
公共类可能组合{
公共静态void printPossibleCombinations(字符串[]选项卡,字符串S)
{
ArrayList used=新的ArrayList();
arraylistnotused=新的ArrayList(Arrays.asList(tab));
可打印组合(已使用、未使用、S、0);
}
私有静态void可打印组合(使用ArrayList,
ArrayList未使用,字符串s,整数位置){
如果(pos==s.length())
{System.out.println(“可能的组合:”);
for(字符串e:已使用)
{
系统输出打印(e+“-”);
System.out.println();
}
}
HashSet前缀=getPossiblePrefixes(s,pos);
for(字符串e:未使用)
{
if(前缀.contains(e))
{
ArrayList isused=新的ArrayList(已使用);
添加(e);
ArrayList isnotused=新的ArrayList(notused);
未使用。移除(e);
可打印组合(已使用、未使用、s、pos+e.长度());
}
}
}
私有静态HashSet getPossiblePrefixes(字符串s,int-pos){
HashSet前缀=新HashSet();

对于(int i=pos;我可能很高兴有a元素的a。这样您就可以更快地识别作为字符串前缀的单词。@凯文:我如何在这个解决方案中集成前缀树?@user199当我们需要确定单词是否是字符串[position…]的前缀时,我们可以遍历前缀树,而不是遍历所有单词。@ILoveCoding:我用java实现了您的解决方案(请参见下面的代码),效果很好。但您不认为不需要使用Tries吗?我只使用了一个方法;getPrefixes(S,pos)这将生成一组可能的前缀。我不知道Trie如何改进这一点。你能解释这一点吗?@user199 Trie可以提高其性能。如果没有性能问题,就不需要Trie。我不会否认这一点。但慢算法总比没有算法好;-)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;


public class PossibleCombination {


    public static void printPossibleCombinations(String[] tab, String S)
    {
        ArrayList<String> used = new ArrayList<String>();
        ArrayList<String> notused = new ArrayList<String>(Arrays.asList(tab));
        printPossibleCombinations(used, notused, S,0);
    }

    private static void printPossibleCombinations(ArrayList<String> used,
            ArrayList<String> notused, String s,int pos) {
            if (pos == s.length())
            {                   System.out.println("Possible combinaiton : ");

                for(String e : used)
                {
                    System.out.print(e + " - ");
                    System.out.println();
                }
            }
            HashSet<String> prefixes = getPossiblePrefixes(s,pos);
            for(String e : notused)
            {

                if (prefixes.contains(e))
                {
                    ArrayList<String> isused = new ArrayList<String>(used);
                    isused.add(e);
                    ArrayList<String> isnotused = new ArrayList<String>(notused);
                    isnotused.remove(e);
                    printPossibleCombinations(isused, isnotused,s, pos + e.length());
                }
            }

    }

    private static HashSet<String> getPossiblePrefixes(String s, int pos) {
        HashSet<String> prefixes = new HashSet<String>();
        for(int i = pos ; i<= s.length() ; i++)
        {
            prefixes.add(s.substring(pos,i));
        }
        return prefixes;
    }

    public static void main(String[] args) {

        String[] tab = {"o","ho","h","tday"};
        String S = "hotday";
        printPossibleCombinations(tab, S);
    }
}