我有一个2D字母数组,每个都有一个分数。例如:
J-95 O-90 H-92 N-99
I-91 0-89 L-55
1-80
T-55
从上面的数组中,我想快速获得前20个左右排列(按分数)的列表。在上面的示例中,列表将是:
JOHN
IOHN
J0HN
I0HN
... etc
我目前正在使用递归函数执行此操作 - 但它比我想要的慢。有没有什么好方法可以快速获得前N名单?我的代码是C ++(如果有很好的库建议)。
由于
我使用Sneftel和Ethan的答案组合解决了这个问题。我使用修剪函数根据权重减少可能的字符,然后根据权重计算排列。
答案 0 :(得分:2)
首先,您需要对候选人进行排序。它需要O(nlgn)时间。
N-99 J-95 H-92 I-91 O-90 0-89 1-80 L-55 T-55
其次,根据您需要的最佳分数,您可以选择前n个字符来进行排列。
(n)*(n-1)*(n-2)*(n-3) / (1 * 2 * 3 * 4) >= m.
n是您选择的候选人数量。 m是您需要的最佳分数。例如,如果您需要20个最佳分数,则只能设置7个字符。可能你面临的问题是你对所有候选人进行排列,而对于一些非常低的候选人来说这是一种浪费。
第三步是获取所需的所有排列,然后对其进行排序和打印。
答案 1 :(得分:2)
这个问题实际上是NP完全的;它是“多选背包问题”(MCKP)的一种形式。
一个可能适合你的简单方法是从每个槽中的前1个字母生成组合,然后是每个槽中的前2个字母,然后是前3个等,并连续两次迭代停止产生相同的前20个分数。这不能保证比强力搜索更有效,但它实现起来很简单,并且适用于“一般”情况。
答案 2 :(得分:0)
有关perm代码的示例,rosetta代码在许多语言this is in c++中都有一些很好的例子。一旦你的排列代码工作,你可以返回biggestcore函数,也可以使用地图将单词映射到分数。
char** permutations(char *word, int len){
... //the perm code
}
//returns array of cstrings permutations
char** returnBiggestScore(char **permutations, int len){
...// your score logic goes here
}
//would return the top five say,
在您的主程序中,您可以执行以下操作:
returnBiggestScores(permutations("hello"));
你如何编写你的回报最高分由你决定,但我建议使用一个地图对象, 这样你可以像往常一样检查任意字母的得分:
score['B']; //fast and convinient returns score value for key 'B'