【发布时间】:2014-09-24 04:10:02
【问题描述】:
给定一个字符串,找到另一个包含输入字符串所有组合的字符串。
示例:
如果输入字符串 = "23",那么它的组合将是 ["22", "23", "32", "33"],
包含上述所有组合的字符串之一是“22233233”,但这不是最短的。最短的是“22332”。
算法应该足够通用以适用于任何大小的输入字符串。 (假设输入不是太大,输出将保持在正常的 int/string/jvm 等大小。还假设输入字符串将仅包含来自英文的字母数字字符)
我尝试了以下算法,但它似乎不起作用:
1) 查找字符串 = ["22", "23", "32", "33"]的所有组合
2) 构建前缀映射 [2: {22, 23}, 3: {32, 33}]
3) 从前缀映射中的任意组合和查找后缀开始。
示例:以 22 开头,后缀为 2 从前缀映射中,对应 2 的值是 22 和 23。 在这里选择一个不是当前选择的单词,所以它会给出 23
4) 将选中的单词的后缀添加到当前字符串(这给出 223)
5) 重复。 所以我会得到 223 的后缀 = 3 从前缀映射,3: {32, 33} 选择任何一个,比如 32 追加到当前字符串得到 2232
6) 如果没有其他匹配项,则追加到当前字符串。这给出了 223233
但是,答案应该是 22332,因为它是最短的。
这是我到目前为止编写的完整代码:
public class TextContainingAllPermutations
{
static String input = "ABC";
public static void main (String args[])
{
int suffixLen = input.length()-1;
Set<String> combinations = getCombinations();
while (suffixLen > 0 && combinations.size() > 1)
{
Map<String, List<String>> suffixToWords = getPrefixMap(combinations, suffixLen);
String someWordsString = combinations.iterator().next();
combinations.remove(someWordsString);
Set<String> combinations2 = new HashSet<String>();
while (combinations.size() > 0)
{
String suffix = someWordsString.substring(someWordsString.length()-suffixLen);
List<String> words = suffixToWords.get(suffix);
if (words == null || words.size()==0)
{
combinations2.add(someWordsString);
System.out.println (someWordsString);
if (combinations.size() == 0)
break;
someWordsString = combinations.iterator().next();
combinations.remove(someWordsString);
}
else
{
String w = words.get(words.size()-1);
words.remove(words.size()-1);
combinations.remove(w);
if (someWordsString.indexOf(w) == -1)
someWordsString += w.charAt(w.length()-1); // append last char
}
}
combinations2.add(someWordsString);
System.out.println (someWordsString);
combinations = combinations2;
suffixLen--;
}
}
private static Map<String, List<String>> getPrefixMap(Set<String> combinations, int suffixLen)
{
Map<String, List<String>> suffixToWords = new HashMap<String, List<String>>();
for (String s: combinations)
{
String suffix = s.substring(0,suffixLen);
if (!suffixToWords.containsKey(suffix))
{
suffixToWords.put(suffix, new ArrayList<String>());
}
suffixToWords.get(suffix).add(s);
}
return suffixToWords;
}
static Set<String> getCombinations()
{
char[] inputChars = input.toCharArray();
int N = (int)Math.pow(input.length(), input.length());
Set<String> combinations = new HashSet<String>(N);
for (int i=0; i<N; i++)
{
char[] binary = padZeroes(Integer.toString(i, input.length())).toCharArray();
String combination = "";
for (int j=0; j<inputChars.length; j++)
{
char c = binary[j];
int index = c - '0';
char inputChar = inputChars[index];
combination = inputChar + combination;
}
System.out.println (new String(binary) + " = " + combination);
combinations.add(combination);
}
return combinations;
}
private static String padZeroes(String s)
{
int j = input.length()-s.length();
for (int i=0; i<j; i++)
s = '0' + s;
return s;
}
}
这不是作业问题。
【问题讨论】:
-
你确定什么会起作用或不会起作用?
-
这个问题似乎是题外话,因为它是一个“给我代码”的问题。你可能应该Take the Tour。
-
这可能不是家庭作业问题,我愿意为您提供怀疑的好处但是......您没有任何努力的迹象,所以很难说服我们否则。
-
@Makoto,我在这里更新了我的算法。我也可以把完整的代码放在这里来展示我的尝试。
-
这肯定会帮助您的事业。提及为什么您认为它不起作用也会有所帮助,因为“它不起作用”并不是对问题的一个很好的描述。尽管我很不愿意承认,但我在工作中使用过一两次,但在问题中添加更多信息通常会得到令人满意的答案。