我这里的代码有两个数组。它排序 arr [] ,因此最高值将在索引0中。现在第二个数组 arr1 [] 包含字符串,我想要应用任何代码的代码更改 arr [] 到 arr1 [] 的位置。因此 arr [0] 将返回6,而 arr1 [0] 将返回字符串“d1”。请注意“d1”与 6 处于同一索引的位置?排序后我想要相同的值仍然有他们的字符串对应物。
我该怎么做呢?
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;
int main() {
int arr[ 5 ] = { 4, 1, 3, 6, 2 };
string arr1[ 5 ] = { "a1", "b1", "c1", "d1", "e1" };
std::sort( arr, arr + 5, std::greater< int >() );
cout << arr[0] << arr1[0] << endl;
system("pause");
}
答案 0 :(得分:31)
不是对数组进行排序,而是对索引进行排序。即,你有
int arr[5]={4,1,3,6,2}
string arr1[5]={"a1","b1","c1","d1","e1"};
你做了
int indices[5]={0,1,2,3,4};
现在你创建一个排序索引比较器,看起来像这样(只是想法,你可能需要稍微修复一下)
class sort_indices
{
private:
int* mparr;
public:
sort_indices(int* parr) : mparr(parr) {}
bool operator()(int i, int j) const { return mparr[i]<mparr[j]; }
}
现在您可以使用stl sort
std::sort(indices, indices+5, sort_indices(arr));
完成后,indices数组将是arr[indices[0]]
是第一个元素。同样arr1[indices[0]]
是相应的一对。
当您尝试对大型数据对象进行排序时,这也是一个非常有用的技巧,您不需要在每次交换时移动数据,只需要移动索引。
答案 1 :(得分:10)
您需要将它们组合在一起,然后对组合对进行排序,然后取消组合对。
int arr[ 5 ] = { ... };
string arr1[ 5 ] = { ... };
pair<int, string> pairs[ 5 ];
for ( int i = 0; i < 5; ++i )
pairs[ i ] = make_pair( arr[ i ], arr1[ i ] );
sort( pairs.begin(), pairs.end() );
for ( int i = 0; i < 5; ++i )
{
arr[ i ] = pairs[ i ].first;
arr1[ i ] = pairs[ i ].second;
}
但实际上,如果arr
和arr1
相关,那么它们应该存储为pair
(或至少是自定义struct
)。这样您就不需要将其用作中间步骤。
答案 2 :(得分:6)
编写自己的迭代器并使用STD:sort。没有第三方库,它可以在不到50行中轻松编码。 交换功能在这里非常重要。
#include <iostream>
#include <iterator> // std::iterator, std::input_iterator_tag
#include <algorithm>
using namespace std;
struct Tuple;
struct RefTuple;
#define TUPLE_COMMON_FUNC(C, D, E, F) \
C##::C## (Tuple& t) ##D \
C##::C## (RefTuple& t) ##D \
void C##::operator = (Tuple& t) ##E \
void C##::operator = (RefTuple& t) ##E \
bool C##::operator < (const Tuple& t) const ##F \
bool C##::operator < (const RefTuple& t) const ##F
#define ASSIGN_1 : i(t.i), j(t.j), s(t.s) {}
#define ASSIGN_2 { i = t.i; j = t.j; s = t.s; }
#define SORT_CRITERIA \
return (j < t.j) || (j == t.j && (i < t.i));
struct Tuple {
int i, j, s;
TUPLE_COMMON_FUNC(Tuple, ; , ; , ;)
};
struct RefTuple {
int &i, &j, &s;
RefTuple(int &x, int &y, int &z): i(x), j(y), s(z) {}
TUPLE_COMMON_FUNC(RefTuple, ; , ; , ;)
};
TUPLE_COMMON_FUNC(Tuple, ASSIGN_1, ASSIGN_2, {SORT_CRITERIA})
TUPLE_COMMON_FUNC(RefTuple, ASSIGN_1, ASSIGN_2, {SORT_CRITERIA})
void swap(RefTuple& t1, RefTuple& t2) {
t1.i ^= t2.i; t2.i ^= t1.i; t1.i ^= t2.i;
t1.j ^= t2.j; t2.j ^= t1.j; t1.j ^= t2.j;
t1.s ^= t2.s; t2.s ^= t1.s; t1.s ^= t2.s;
}
class IterTuple : public iterator<random_access_iterator_tag, Tuple> {
int *i, *j, *s, idx;
public:
IterTuple(int* x, int*y, int* z, int l) : i(x), j(y), s(z), idx(l) {}
IterTuple(const IterTuple& e) : i(e.i), j(e.j), s(e.s), idx(e.idx) {}
RefTuple operator*() { return RefTuple(i[idx], j[idx], s[idx]); }
IterTuple& operator ++ () { idx++; return *this; }
IterTuple& operator -- () { idx--; return *this; }
IterTuple operator ++ (int) { IterTuple tmp(*this); idx++; return tmp; }
IterTuple operator -- (int) { IterTuple tmp(*this); idx--; return tmp; }
int operator - (IterTuple& rhs) { return idx - rhs.idx; }
IterTuple operator + (int n) { IterTuple tmp(*this); tmp.idx += n; return tmp; }
IterTuple operator - (int n) { IterTuple tmp(*this); tmp.idx -= n; return tmp; }
bool operator==(const IterTuple& rhs) { return idx == rhs.idx; }
bool operator!=(const IterTuple& rhs) { return idx != rhs.idx; }
bool operator<(IterTuple& rhs) { return idx < rhs.idx; }
};
int Ai[10] = {0, 0, 2, 3, 2, 4, 1, 1, 4, 2};
int Aj[10] = {0, 2, 3, 4, 4, 4, 0, 1, 0, 2};
int Ax[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int main () {
IterTuple from(Ai, Aj, Ax, 0);
IterTuple until(Ai, Aj, Ax, 10);
sort(from, until);
for (IterTuple it = from; it != until; it++)
cout << (*it).i << ' ' << (*it).j << ' ' << (*it).s << '\n';
return 0;
}
答案 3 :(得分:0)
我相信编写自己的QuickSort变体更简单,结果将比使用索引映射自定义迭代器或数组更好。
QuickSort不稳定排序。
val tips = /*...*/
fun main(args: Array<String>) {
val (title, text) = TipProvider.next()
println("$title: $text")
}
object TipProvider {
var tipPool = mutableListOf<String>()
fun next(): Pair<String, String> {
if(tipPool.isEmpty()) {
// create copy of keys
tipPool = mutableListOf(*(tips.keys.shuffled().toTypedArray()))
}
val nextTipKey = tipPool.first()
tipPool.remove(nextTipKey)
return nextTipKey to tips[nextTipKey]!!
}
}