2D 点的排列
Permutations of 2D points
我想探索 2d 点的所有排列(2D 数组中的 x, y 坐标)我的 2d 点结构是:
struct pos_t {
int x; int y;
pos_t(){x = 0 ; y = 0;}
pos_t(int X, int Y){x=X; y=Y;}
pos_t(pos_t const & r) {x = r.x; y=r.y;}
pos_t& operator=(pos_t const & r) {x = r.x; y=r.y; return *this;}
bool operator < ( pos_t& p2)
{
return (x+y) < (p2.x+p2.y);
}
friend ostream& operator << (ostream &o, const pos_t& p)
{
return o << "(" << p.x << "," << p.y << ")";
}
};
使用pos_t向量称为 treasurePos ( vector<pos_t>
),我使用下面的代码来迭代其他不同的排列并显示每个排列。
do {
copy(begin(treasurePos), end(treasurePos), ostream_iterator<pos_t>(cout, " -> "));
cout << endl;
} while ( std::next_permutation(begin(treasurePos),end(treasurePos)) );
但是在我的向量中有以下pos_t元素:(0,2) 和 (1,0)我只得到一种排列:(0,2) -> (1,0) ->
我期望有:
(0,2) -> (1,0) ->
(1,0) -> (0,2) ->
另一个例子,有 4 个点,我只得到 2 个置换:
(1,3) -> (2,2) -> (3,0) -> (3,1) ->
(1,3) -> (2,2) -> (3,1) -> (3,0) ->
你有什么想法吗?
当新排列在字典上不大于旧排列时,next_permutation
false
。
由于您的排序说(1,0)
小于(0,2)
,序列{(1,0), (0,2)}
在字典上小于{(0,2), (1,0)}
,并且立即false
next_permutation
。
同样的原因在你的四点例子背后。
如果要遍历所有排列,则应首先对序列进行排序。
在 molbdnil 答案之上。要获得所有排列,应对初始集进行排序。所以,这应该可以解决问题。
std::sort(begin(treasurePos), end(treasurePos));
do {
copy(begin(treasurePos), end(treasurePos), ostream_iterator<pos_t>(cout, " -> "));
cout << endl;
} while ( std::next_permutation(begin(treasurePos),end(treasurePos)) );
最后,我找到了为什么即使打电话给sort
,我也永远不会得到所有的排列(见我的答案......),但再次感谢您的帮助。
在给next_permutation
打电话之前,所有提到打电话给std::sort
的答案都是正确的(这就是为什么我对大多数答案投了赞成票)。但实际上,这里最重要的是要注意lexicographic
顺序取决于您使用的比较运算符。
默认参数是bool operator < ( ... )
,但对于我提供的实现(见下文),(1,3)等于(3,1)。
bool operator < ( pos_t& p2)
{
return (x+y) < (p2.x+p2.y);
}
这就是为什么我永远不会得到排列(即对于 N 个不同的元素,我们得到 N! 排列)
要pos_t
的正确运算符是:
bool operator < ( pos_t const & p) const
{
return (x < p.x) || ((x == p.x) && (y < p.y));
}
现在我们可以对所有排列进行排序、循环和收集。
std::sort(begin(treasurePos), end(treasurePos));
do {
vector<pos_t> c;
copy(begin(treasurePos), end(treasurePos), back_inserter(c));
copy(begin(c), end(c), ostream_iterator<pos_t>(cout, " -> "));
cout << endl;
treasure_order.push_back(c);
} while ( std::next_permutation(begin(treasurePos),end(treasurePos)) );
cout << "we stored " << treasure_order.size() << " path to get all the treasure (=nbTreasure! = " << fact((int)treasurePos.size()) << ")" << endl;
为了使 std::next_permutation 给出所有排列,您的初始向量应该在循环之前使用相同的比较器进行排序。
从 cplusplus.com:
将范围 [第一个、最后一个) 中的元素重新排列到下一个按字典顺序排列的更大排列中。
可以根据它们在词典上相互比较的方式对不同的排列进行排序;第一个这样的排序可能排列(将字典上较小的排列与所有其他排列进行比较的排列)是按升序排列的所有元素排序的排列,而最大的排列的所有元素都按降序排序。
如果函数可以确定下一个更高的排列,它将重新排列元素并返回 true。如果这是不可能的(因为它已经处于最大可能的排列),它会根据第一个排列(按升序排序)重新排列元素并返回 false。
所以基本上,如果你想让它工作,起始排列必须是最小的
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 2D数组来自文本输入,中间有空格
- 将值指定给向量(2D)的向量中的某个位置
- 为什么不;名字在地图上是按顺序排列的吗
- 如何使用用户输入在C++中正确填充2D数组
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 按对象的特定方法按升序排列的C++优先级队列
- 如何在C++中检查2D数组中负值的输入验证
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 在 2D 向量中使用第三个 [ ] 有什么意义?
- 四边形的 2D 旋转
- 打印第二列时的2d字符矢量打印空间
- 找到具有最多子串栅栏的字符串排列
- 如何将以逗号和空格分隔的整数读取到 2D 数组中?
- 如何在C++函数中声明静态 2D 数组?
- 我是 C++ 的初学者,我想知道如何在 2D 矢量中获取重复值
- 排列 2D 数组中的元素
- 如何检查 2D 数组在 c++ 中是否按升序排列?
- 2D 点的排列
- 如何创建 2D 字符串数组的排列