【发布时间】:2013-04-15 14:51:25
【问题描述】:
我想按以下方式对两个大小相同的数组 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 (因为排序需要随机访问)。现在我的问题是,我真的不太擅长 C++。如果有人可以在菜鸟可以理解的水平上给我提示,我会很高兴。我找到了一些解决方案:
Sorting two corresponding arrays,但是两个提议的解决方案似乎都不够性能,
http://www.stanford.edu/~dgleich/notebook/2006/03/sorting_two_arrays_simultaneou.html 它使用了我认为违反 stl 的 boost 内容(老实说,我不了解那里使用的所有模板内容,我有一个 double 和一个 int 数组以及两者的大小 n,所以我不要认为我需要模板),最后是这个
http://www.c-plusplus.de/forum/313698-full 解决方案我被困在我不知道如何实现 operator-> 和 operator* 因为我不知道我是否只能返回一个值(来自数组 a 的值),即,如果此值仅用于比较或分配值。该线程中的解决方案还比较了比较运算符的指针值,我不确定这是否正确(不应该是指针后面的值吗?)。
这是我到目前为止所拥有的,如果你看到可怕的菜鸟错误,请告诉我我哪里出错了:)
#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);
}
如果有人还没有停止阅读并且仍然有耐心,我对我刚刚从这里 http://www.c-plusplus.de/forum/313698-full 复制的“diff_type”、“reference”和“pointer”类型感到困惑,它们应该是什么?
【问题讨论】:
-
普通指针是随机访问迭代器。你可能只是使用它们。
-
您好,Arne,感谢您的回复。我想将迭代器传递给排序函数,为了对两个数组进行排序,我需要同时遍历两个数组。
-
我明白了,我在第一次阅读您的问题时并不太清楚 - 请忘记我的评论;)
-
你可能想看看 boost.operators,尤其是他们提供的迭代器助手——他们会为你定义大部分的操作符,typedef 等等。 wrt 取消引用运算符:是的,您应该(并且可以)只返回一个指向两个元素之一的指针。您可以模板化您的迭代器类,让运算符返回指向第一个或第二个元素的指针。
-
我很难理解这句话 - “数组 b 的排序方式与数组 b 的排序方式相同”。你能澄清一下你的意思吗?