我在这里发布这篇文章,尽管关于这个问题已经发布了很多。我不想发布答案,因为它不起作用。这篇文章的答案(在所有可能的重复排列列表中查找给定字符串的排名)对我来说不起作用。
所以我尝试了这个(这是我剽窃的代码的汇编,也是我处理重复的尝试)。不重复的案例工作正常。BOOKKEEPER生成83863,而不是所需的10743。
(阶乘函数和字母计数器数组“repeats”工作正常。我没有发布以节省空间。)
while (pointer != length)
{
if (sortedWordChars[pointer] != wordArray[pointer])
{
// Swap the current character with the one after that
char temp = sortedWordChars[pointer];
sortedWordChars[pointer] = sortedWordChars[next];
sortedWordChars[next] = temp;
next++;
//For each position check how many characters left have duplicates,
//and use the logic that if you need to permute n things and if 'a' things
//are similar the number of permutations is n!/a!
int ct = repeats[(sortedWordChars[pointer]-64)];
// Increment the rank
if (ct>1) { //repeats?
System.out.println("repeating " + (sortedWordChars[pointer]-64));
//In case of repetition of any character use: (n-1)!/(times)!
//e.g. if there is 1 character which is repeating twice,
//x* (n-1)!/2!
int dividend = getFactorialIter(length - pointer - 1);
int divisor = getFactorialIter(ct);
int quo = dividend/divisor;
rank += quo;
} else {
rank += getFactorialIter(length - pointer - 1);
}
} else
{
pointer++;
next = pointer + 1;
}
}
我会说大卫·波斯特(被接受的答案)超级酷。然而,我想进一步提高它的速度。内部循环试图找到逆序对,并且对于每一个这样的逆序,它试图促进秩的增加。如果我们在该位置使用有序映射结构(二进制搜索树或BST),我们可以简单地从第一个节点(左下角)开始按顺序遍历,直到它到达BST中的当前字符,而不是遍历整个映射(BST)。在C语言中,std::map是BST实现的完美工具。下面的代码减少了循环中必要的迭代次数,并删除了if检查。
long long rankofword(string s)
{
long long rank = 1;
long long suffixPermCount = 1;
map<char, int> m;
int size = s.size();
for (int i = size - 1; i > -1; i--)
{
char x = s[i];
m[x]++;
for (auto it = m.begin(); it != m.find(x); it++)
rank += suffixPermCount * it->second / m[x];
suffixPermCount *= (size - i);
suffixPermCount /= m[x];
}
return rank;
}
如果我们使用数学,复杂性将会降低,并且能够更快地找到等级。这对于大型字符串特别有用。(更多详细信息可在此处找到)
注:此答案适用于以1为基础的排名,如示例所示。下面是一些Python,它至少适用于所提供的两个示例。关键的事实是subfixperms*ctr[y]//ctr[x]
是排列的数量,其第一个字母是y
长度的(i 1)
后缀。
from collections import Counter
def rankperm(perm):
rank = 1
suffixperms = 1
ctr = Counter()
for i in range(len(perm)):
x = perm[((len(perm) - 1) - i)]
ctr[x] += 1
for y in ctr:
if (y < x):
rank += ((suffixperms * ctr[y]) // ctr[x])
suffixperms = ((suffixperms * (i + 1)) // ctr[x])
return rank
print(rankperm('QUESTION'))
print(rankperm('BOOKKEEPER'))
Java版本:
public static long rankPerm(String perm) {
long rank = 1;
long suffixPermCount = 1;
java.util.Map<Character, Integer> charCounts =
new java.util.HashMap<Character, Integer>();
for (int i = perm.length() - 1; i > -1; i--) {
char x = perm.charAt(i);
int xCount = charCounts.containsKey(x) ? charCounts.get(x) + 1 : 1;
charCounts.put(x, xCount);
for (java.util.Map.Entry<Character, Integer> e : charCounts.entrySet()) {
if (e.getKey() < x) {
rank += suffixPermCount * e.getValue() / xCount;
}
}
suffixPermCount *= perm.length() - i;
suffixPermCount /= xCount;
}
return rank;
}
未排序排列:
from collections import Counter
def unrankperm(letters, rank):
ctr = Counter()
permcount = 1
for i in range(len(letters)):
x = letters[i]
ctr[x] += 1
permcount = (permcount * (i + 1)) // ctr[x]
# ctr is the histogram of letters
# permcount is the number of distinct perms of letters
perm = []
for i in range(len(letters)):
for x in sorted(ctr.keys()):
# suffixcount is the number of distinct perms that begin with x
suffixcount = permcount * ctr[x] // (len(letters) - i)
if rank <= suffixcount:
perm.append(x)
permcount = suffixcount
ctr[x] -= 1
if ctr[x] == 0:
del ctr[x]
break
rank -= suffixcount
return ''.join(perm)
基于当前的实现,我将从某个来源获得一个数组列表,其中包含大约1000个按字母排序的唯一名称(A-Z或Z-A)。 我需要找到以给定字母表开头的第一个单词的索引。 因此,更准确地说,当我选择一个字母表,例如“M”时,它应该给我排序列表中以“M”开头的单词第一次出现的索引。 这样我就可以找到26个字母中每个字母开头的所有单词的索引。 请帮我找到一个不影响速度的解决方案。 更新时间: 实际上,在获得100
这是我的数据样本 我编写了以下代码,它删除了所有分类列(例如)。但是,一些非类别列具有值。如何将它们从我的数据集中排除。 当我运行程序时,我得到错误来说太大的值,我认为这是由于值造成的。 问题1-我如何完全删除这些行问题2-这些列的类型是什么,大部分是NO。但两者之间有短信吗?我想我将执行,但这并没有给出结果
我有这个字符串列表 我想根据其中的数字对这个列表进行排序。 例如,如果我有,我希望它像一样排序。 我使用了,但它返回类似的内容。 我应该怎么做才能把它按正确的顺序排列?
问题内容: 这个问题已经在这里有了答案 : 如何使用SQL Order By语句对不区分大小写的结果进行排序? (3个答案) 4年前关闭。 我要做的就是按字母顺序抓取东西,而忽略大写字母。 这是我在上面使用的代码,但是它总是给我一个SQLite异常,表明COLLATE是语法错误。 android.database.sqlite.SQLiteException:在“ COLLATE”附近:语法错误:
我有一个表,有以下列 我想要一个查询(下面查询的修改版本),如果上面的表中给定的work_date和员工ID(GROUP BYEMP_ID和WORK_DATE)超过1行,它将返回一行。所以我写了如下查询: 例如: 如果我通过1/1/2013 for:p_WorkDate,查询应返回如下: 基本上,我试图找出EMP\u ID和WORK\u DATE是否有超过1行,但还有一个额外的要求,即元素列包含什
我有很多数据在一个目录,我想找到任何实例的双字不是数字。我从这里开始: 并将其扩展到包括我不希望在结果中出现的内容: 要忽略的样本数据: 比重1点零零七
问题内容: 在java中查找字符串的所有排列 问题答案: 在这篇文章中,我们将看到如何在 java 中找到 String 的所有排列。 我们将使用一种非常简单的方法来做到这一点。 取出String的第一个字符,递归地插入剩余String的排列的不同位置。 假设您将 String 作为ABC。 所以我们从 ABC 中取出 A 第一个字符 =A 和 RemainingString = BC 因为我们在
问题内容: 我是Java的新手,正在尝试按字母顺序排列术语的arrayList。(一个术语定义为一个字符和一个整数)(例如 我的代码如下: 为什么这不起作用?以及我该如何完成呢?我的arrayList称为术语,填充有Term类型 问题答案: 您在这行代码中遇到的问题。您的课程不是So 的类型,这两个对象将基于哪个属性或条件方法? 您必须使您的类为Comparable类型。和,根据您的需要覆盖该方法