【发布时间】:2020-12-06 05:57:55
【问题描述】:
给定一个节点子集 {1,2,...,N} 是否有任何 STL 或 boost 函数返回对所有节点的唯一无向游览?
std::next_permutation() 提供所有N! 定向 游览,其中1-2-...-N 与N-N-1-...-2-1 不同。
但是,在这种情况下,我不想要他们两个,而只想要其中一个。本质上,我只想列举N! / 2 的旅行。
以下使用std::next_permutation() 和unordered_set 的代码可以工作,但是还有什么更高效的吗?以下代码实质上生成了所有N! 定向游览,并在与unordered_set() 核对后丢弃了其中的一半。
#include <vector>
#include <unordered_set>
#include <algorithm>
#include <boost/functional/hash.hpp>
template <typename T, typename U> bool unorderedset_val_there_already_add_if_not(std::unordered_set<T, U>& uos, T& val) {
if (uos.find(val) != uos.end())
return true;//val already there
uos.insert(val);
return false;//Value is new.
}
int main() {
std::vector<int> sequence{ 1, 2, 3};
std::unordered_set<std::vector<int>, boost::hash<std::vector<int>>> uos;
do {
printf("Considering ");
for (std::size_t i = 0; i < sequence.size(); i++)
printf("%d ", sequence[i]);
printf("\n");
std::vector<int> rev_sequence = sequence;
std::reverse(rev_sequence.begin(), rev_sequence.end());
if (unorderedset_val_there_already_add_if_not(uos, sequence) || unorderedset_val_there_already_add_if_not(uos, rev_sequence)) {
printf("Already there by itself or its reverse.\n");
}
else {
printf("Sequence and its reverse are new.\n");
}
} while (std::next_permutation(sequence.begin(), sequence.end()));
getchar();
}
也就是说,给定{1,2,3},我只想枚举(1-2-3)、(1-3-2)和(2-1-3)。其他三个排列 (2-3-1)、(3-1-2) 和 (3-2-1) 不应枚举,因为它们的相反顺序已经枚举。
【问题讨论】: