This answer通过比较它们的内容来确定两个字符串是否是排列。如果它们包含相同数量的每个字符,则它们显然是排列。这是在 O(N)时间内完成的。
我不喜欢这个答案,因为它重新发明了is_permutation
的目的。也就是说,is_permutation
的复杂性为:
谓词的最多 O(N 2 )应用程序,如果序列已经相等,则完全 N ,其中{{1 }}
所以我不能提倡使用N=std::distance(first1, last1)
,它比手动旋转算法慢几个数量级。但是,该标准的实施者肯定不会错过这种明显的改进吗?那么为什么is_permutation
O(N 2 )?
答案 0 :(得分:9)
is_permutation
适用于几乎所有数据类型。链接中的算法仅适用于具有少量值的数据类型。
这与std::sort
为O(N log N)的原因相同,但计数排序为O(N)。
答案 1 :(得分:7)
是我写了那个答案。
当字符串的value_type
为char
时,查找表中所需的元素数为256.对于双字节编码,为65536.对于四字节编码,查找表将有超过40亿条目,可能大小为16 GB!其中大部分都没用过。
首先要认识到即使我们将类型限制为char
和wchar_t
,它仍然可能无法维持。同样,如果我们想对is_permutation
类型的序列执行int
。
对于大小为1或2字节的整数类型,我们可以对std::is_permutation<>
进行专门化。但这有点让人想起std::vector<bool>
,回想起来并不是每个人都认为这是一个好主意。
我们也可以使用基于std::map<T, size_t>
的查找表,但这可能是分配量很大,因此可能不是性能获胜(或者至少,并非总是如此)。但是,为了进行详细的比较,可能值得实施一个。
总之,我没有对C ++标准提出错误,因为is_permutation
没有包含char
的高性能版本。首先,因为在现实世界中,我不确定它是模板的最常见用法,其次是因为STL不是算法的全部和最终,特别是在领域知识可以是用于加速特殊情况的计算。
如果事实证明is_permutation
char
在野外非常普遍,那么C ++库实现者将有权为它提供专业化。
答案 2 :(得分:4)
您引用的答案适用于char
。它假定它们是8位(不一定是这种情况),因此每个值只有256种可能性,并且您可以便宜地从每个值转到数字索引以用于计数的查找表(对于{{1}在这种情况下,值和索引是相同的东西!)
它生成每个字符串中每个char
值出现的次数;那么,如果两个字符串的这些分布相同,则字符串是彼此的排列。
时间复杂度是多少?
因此,总体时间复杂度为O(N + M):线性,如您所述。
现在,char
对其输入没有做出这样的假设。它不知道只有256种可能性,或者它们确实是有界限的。它不知道如何从输入值转到它可以用作索引的数字,更不用说如何在恒定时间内这样做。它唯一知道的是如何比较两个值的相等性,因为调用者提供了这些信息。
所以,时间复杂度:
所以复杂性最多只能是二次方。