我想按以下方式对两个相同大小的数组a和b进行排序:数组b的排序顺序与数组a的排序方式相同。示例输入:
a = {3, 1, 5}
b = {2, 6, 4}
示例
a = {1, 3, 5}
b = {6, 2, 4}
这样b的值与它们的重新排序无关,而是跟随数组a的重新排序。
我想使用stl :: sort来做到这一点,我需要尽可能高效地完成它。因此,我不想将所有元素复制到结构体中或者使用索引对数组进行排序,之后我可以使用该数组来排序数组a和b。我认为最小的开销应该是RandomAccessIterator(因为sort需要随机访问)。现在我的问题是,我在C ++中真的不太好。如果有人可以给我一个级别的提示,那么诺布就能理解我会很高兴。我找到了一些解决方案:
Sorting two corresponding arrays,但两种提议的解决方案似乎都不够高效,
http://www.stanford.edu/~dgleich/notebook/2006/03/sorting_two_arrays_simultaneou.html使用了boost我认为违反了stl的东西(老实说我不明白那里使用的所有模板东西,我有一个double和一个int数组,两者的大小为n,所以我认为我不需要模板),最后这个
http://www.c-plusplus.de/forum/313698-full解决方案,我不知道如何实现operator->和operator *因为我不知道我是否只返回一个值(数组a中的值),即该值是仅用于比较还是用于赋值。此线程中的解决方案还比较了比较运算符的指针值,我不确定它是否正确(不应该是指针后面的值?)。
到目前为止,这是我所拥有的,如果你看到可怕的noob错误请告诉我哪里出错了。)
#include "DoubleArrayRAccIterator.h"
DoubleArrayRAccIterator::~DoubleArrayRAccIterator() {
// TODO Auto-generated destructor stub
}
struct doubleValue{
double* a_val;
int* b_val;
};
double::DoubleArrayRAccIterator::DoubleArrayRAccIterator(double& a_arr,int& b_arr, int size) {
a_begin = &a_arr;
b_begin = &b_arr;
a = &a_arr;
b = & b_arr;
n = size;
}
DoubleArrayRAccIterator::DoubleArrayRAccIterator() {
a = 0;
b = 0;
n = 0;
}
DoubleArrayRAccIterator::DoubleArrayRAccIterator(const DoubleArrayRAccIterator& it) {
a = it.a;
b = it.b;
n = it.n;
}
DoubleArrayRAccIterator& DoubleArrayRAccIterator::operator=(const DoubleArrayRAccIterator& it) {
a = it.a;
b = it.b;
n = it.n;
return *this;
}
DoubleArrayRAccIterator& DoubleArrayRAccIterator::operator++() {
++a;
++b;
return *this;
}
DoubleArrayRAccIterator& DoubleArrayRAccIterator::operator--() {
--a;
--b;
return *this;
}
DoubleArrayRAccIterator DoubleArrayRAccIterator::operator++(int) {
DoubleArrayRAccIterator it(*this);
++a;
++b;
return it;
}
DoubleArrayRAccIterator DoubleArrayRAccIterator::operator--(int) {
--a;
--b;
return *this;
}
DoubleArrayRAccIterator& DoubleArrayRAccIterator::operator+=(diff_type x) {
a += x;
b += x;
return *this;
}
DoubleArrayRAccIterator& DoubleArrayRAccIterator::operator-=(diff_type x) {
a += x;
b += x;
return *this;
}
DoubleArrayRAccIterator DoubleArrayRAccIterator::operator+(diff_type x) const {
a += x;
b += x;
return *this;
}
typename DoubleArrayRAccIterator DoubleArrayRAccIterator::operator-(diff_type x) const {
a -= x;
b -= x;
return *this;
}
DoubleArrayRAccIterator DoubleArrayRAccIterator::operator+(const DoubleArrayRAccIterator& it) const {
a += it.a;
b += it.b;
return *this;
}
DoubleArrayRAccIterator DoubleArrayRAccIterator::operator-(const DoubleArrayRAccIterator& it) const {
a -= it.a;
b -= it.b;
return *this;
}
DoubleArrayRAccIterator::reference DoubleArrayRAccIterator::operator*() const {
// this MUST be wrong, only return value of array a?
doubleValue result;
result.a_val=a;
result.b_val=b;
return *result;
}
DoubleArrayRAccIterator::pointer DoubleArrayRAccIterator::operator->() const {
// this MUST be wrong, only return value of array a?
doubleValue result;
result.a_val=a;
result.b_val=b;
return &result;
}
DoubleArrayRAccIterator::reference DoubleArrayRAccIterator::operator[](diff_type x) const {
// this MUST be wrong, only return value of array a?
doubleValue result;
result.a_val=a_begin+x;
result.b_val=b_begin+x;
return *result;
}
bool DoubleArrayRAccIterator::operator==(const DoubleArrayRAccIterator& it) const {
return a == it.a;
//compare indices or values here?
}
bool DoubleArrayRAccIterator::operator!=(const DoubleArrayRAccIterator& it) const {
return a != it.a;
//compare indices or values here?
}
bool DoubleArrayRAccIterator::operator<(const DoubleArrayRAccIterator& it) const {
//compare indices or values here?
}
bool DoubleArrayRAccIterator::operator>(const DoubleArrayRAccIterator& it) const {
//compare indices or values here?
}
bool DoubleArrayRAccIterator::operator<=(const DoubleArrayRAccIterator& it) const {
//compare indices or values here?
}
bool DoubleArrayRAccIterator::operator>=(const DoubleArrayRAccIterator& it) const {
//compare indices or values here?
}
DoubleArrayRAccIterator begin() {
return DoubleArrayRAccIterator(a_begin, b_begin, n);
}
DoubleArrayRAccIterator end() {
return DoubleArrayRAccIterator(a_begin + n, b_begin + n, n);
}
如果有人没有停止阅读并且仍然有耐心,我会对我刚从这里复制的“diff_type”,“reference”和“pointer”类型感到困惑http://www.c-plusplus.de/forum/313698-full,他们认为是什么是吗?
答案 0 :(得分:3)
如果我理解你的话你就是这样:
[a1][a2][a3]....[an]
[b1][b2][b3]....[bn]
您希望以相同的方式按数组a排序这两个数组,因此结果为:
[ax1][ax2][ax3]....[axn]
[bx1][bx2][bx3]....[bxn]
其中xi
对于两个数组都是相同的。
考虑这个例子:
class SIter {
public:
SIter(int* aIter, double* bIter) : aIter(aIter), bIter(bIter) {}
// we move to next position is just moving both:
SIter& operator ++() {
++aIter; ++bIter;
return *this;
}
SIter operator ++(int) {
SIter rv = *this;
++aIter; ++bIter;
return rv;
}
SIter& operator --() {
--aIter; --bIter;
return *this;
}
SIter operator --(int) {
SIter rv = *this;
--aIter; --bIter;
return rv;
}
SIter operator + (std::ptrdiff_t cc) const
{
SIter rv = *this;
rv.aIter += cc;
rv.bIter += cc;
return rv;
}
SIter operator - (std::ptrdiff_t cc) const
{
SIter rv = *this;
rv.aIter -= cc;
rv.bIter -= cc;
return rv;
}
std::ptrdiff_t operator - (SIter other) const
{
return aIter - other.aIter;
}
struct value_type {
int a; double b;
bool operator < (const value_type& other) const {
return a < other.a; // this is the place where way of sorting is defined!!!!
}
};
struct reference {
int* a;
double* b;
reference& operator = (const value_type& o)
{
*a = o.a;
*b = o.b;
return *this;
}
operator value_type() const {
value_type rv = { *a, *b };
return rv;
}
reference& operator = (const reference& other)
{
*a = *other.a;
*b = *other.b;
return *this;
}
bool operator < (const reference& other) const {
return *a < *other.a;
}
bool operator < (const value_type& other) const {
return *a < other.a;
}
};
reference operator * () {
reference rv = { aIter, bIter };
return rv;
}
bool operator == (const SIter& other) const
{
return aIter == other.aIter; // don't need to compare bIter - shall be in sync
}
bool operator != (const SIter& other) const
{
return aIter != other.aIter; // don't need to compare bIter - shall be in sync
}
bool operator < (const SIter& other) const
{
return aIter < other.aIter; // don't need to compare bIter - shall be in sync
}
// I bet you don't need pointer operator -> ()
typedef std::random_access_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
typedef reference pointer;
private:
int* aIter;
double* bIter;
};
然后像这样使用:
int main() {
int a[100] = {};
double b[100] = {};
SIter beginIter(a, b);
SIter endIter(a + 100, b + 100);
std::sort(beginIter, endIter);
}
我没有尝试这个,可能它有一些缺点,但你应该朝着这个方向前进。你的迭代器应该包含两个指向你的数组的指针(更通用的方式 - 容器的迭代器),你的引用类型应该有operator =
和operator <
,它们可以分配你的两个数组的元素并且只比较一个数组的元素。
<强> [UPDATE] 强>
好消息:我做了一个工作示例:ideone
答案 1 :(得分:0)
我对你的问题感到有些困惑,但是由于你链接到this问题,我假设你正试图解决同样的问题,即你想要排序数组a
和您希望数组b
的索引重新排列方式与a
的方式相同。
这听起来像是XY Problem。如果可能的话,重新设计您的代码,以便您没有parallel arrays。相反,将a
的每个元素及其对应的b
元素放在一个类或std::pair
中,将那些放在一个集合中,例如数组或向量,并排序(如果需要,可能会重载比较运算符)。