0

ベクトルの並べ替えや動的に割り当てられた配列の例がありますが、静的配列に関するヘルプは見つかりませんでした。配列があるとしましょう

int array[10][10];

と比較関数、

bool compare(const int (*a)[10], const int (*b)[10]);

このように呼ぶと、

std::sort(array, array + 10, compare);

コンパイルエラーがあります:error: cannot convert 'int*' to 'const int (*)[10]' in argument passing

配列をソート関数にキャストするなど、さまざまな方法を試しまし(void**)たが、セグメンテーション違反が発生しました。私の問題は、私が推測する関数パラメーターとして配列を使用することですが、このstd::sortの使用方法を理解できませんでした。それ以外の場合は、独自のソート関数を作成する必要があります。

4

3 に答える 3

2

std::sortタイプの要素のコンテナでが呼び出されると、T比較関数はタイプTまたはの引数を受け取る必要がありますconst T&。この場合、2次元配列があるため、要素のタイプは1次元配列int[10]です。1次元配列はポインターに減衰するため、次のcompareようになります。

bool compare(int a[10], int b[10]);

または同等に:

bool compare(int *a, int *b);

これにより、発生したエラーは修正されますが、コードは機能しません。std::sortコンテナ要素を割り当て可能(またはC ++ 11で移動可能)にする必要がありますが、配列は割り当て可能ではありません。

std::vector<std::vector<int> >人々が提案したように、代わりに使用することができます。パフォーマンスの問題に対する懸念は誤っていることに注意してください。2次元配列の並べ替えが可能であったとしても、1次元配列のコピーが多くなり、時間がかかります。一方、ベクトルの交換は、ポインターを交換するだけで実行され、より高速です。一般に、最初にテストしていない場合は、パフォーマンスについて推測するべきではありません。

于 2012-12-18T01:11:15.360 に答える
1

STLとC++を使用する場合は、モダンなスタイルで記述して、実際にSTLを使用してみましょう。

最新のc++11を使用した問題の私の試み:

#include <vector>
#include <iostream>
#include <algorithm>

typedef std::vector<int> ArrayInt;
typedef std::vector< std::vector<int> > ArrayData;

bool compare(const ArrayInt& a, const ArrayInt& b) {
    std::cout << &(a) << ' ' << &(b) << std::endl;
    int sumA = std::accumulate(a.begin(), a.end(), 0);
    int sumB = std::accumulate(b.begin(), b.end(), 0);
    return sumA < sumB;
}

int main(int argc, char** argv) {
    ArrayData array = {
        {1,2,4,0,3,7,6,8,3,3},
        {13,2,4,0,3,7,6,8,3,3},
        {10,2,4,0,3,7,6,8,3,3},
        {1,2,4,0,3,7,6,8,3,3},
        {16,2,4,0,3,7,6,8,3,3},
        {1,2,400,0,3,7,6,8,3,3},
        {1,2,4,0,3,7,6,8,3,3},
        {120,2,4,0,3,7,6,8,3,3},
        {1,2,4,0,3,7,6,8,3,3},
        {1,2,4,0,3,7,6,8,3,3}
    };
    std::sort(array.begin(), array.end(), compare);
    for (auto row : array) {
        for (int num : row)
            std::cout << num << ' ';
        std::cout << std::endl;
    }
}

これは、accumulateを使用して各サブ配列を合計し、合計で並べ替えます。同じ行を複数回合計する必要があるため、非常に非効率的です。ただし、カスタム比較関数を表示するためだけにあります。


演習として、ソートの前に、非同期を使用して合計部分を使用可能なコアに分散して合計を実行するこのバージョンを作成しました。少し話題から外れてすみません。私はそれがまだ何人かの人々に役立つことを願っています:

#include <vector>
#include <iostream>
#include <algorithm>
#include <future>

typedef std::vector<int> IntRow;
typedef std::pair<int, IntRow> DataRow;
typedef std::vector<DataRow> DataTable;

int main(int argc, char** argv) {
    // Holds the sum of each row, plus the data itself
    DataTable array = {
        {0, {1,2,4,0,3,7,6,8,3,3}},
        {0, {13,2,4,0,3,7,6,8,3,3}},
        {0, {10,2,4,0,3,7,6,8,3,3}},
        {0, {1,2,4,0,3,7,6,8,3,3}},
        {0, {16,2,4,0,3,7,6,8,3,3}},
        {0, {1,2,400,0,3,7,6,8,3,3}},
        {0, {1,2,4,0,3,7,6,8,3,3}},
        {0, {120,2,4,0,3,7,6,8,3,3}},
        {0, {1,2,4,0,3,7,6,8,3,3}},
        {0, {1,2,4,0,3,7,6,8,3,3}}
    };
    // Make use of multiple cores if it's efficient enough
    // get the sum of each data row
    std::vector<std::future<int>> sums(array.size());
    auto next = sums.begin();
    for (auto& row : array)
        *next++ = std::async([](const IntRow& row) { return std::accumulate(row.begin(), row.end(), 0); }, row.second);
    // Get the results
    auto nextRow = array.begin();
    for (auto& sum: sums)
        (*nextRow++).first = sum.get();
    // Sort it 
    std::sort(array.begin(), array.end(),
              [](const DataRow& a, const DataRow& b) { return a.first < b.first; });
    // Print it
    for (auto row : array) {
        for (int num : row.second)
            std::cout << num << ' ';
        std::cout << std::endl;
    }
}

pthreadライブラリなどでコンパイルする必要があります。

g++ -O6 sort.cpp --std=c++11 -g -lpthread

于 2012-12-18T00:32:47.233 に答える
1

比較関数は、渡された要素へのイテレータを取得しませんが、逆参照されたイテレータ、つまり値型を取得します。したがって、比較関数は次のように宣言する必要があります。

bool compare(int (&a0)[10], int (&a1)[10]);

配列イテレータを使用して実際に呼び出すことができることを確認できます。

compare(*(std::begin(array) + 0), *(std::begin(array) + 1));

ただし、これでは配列を並べ替えることはできません。組み込みの配列はコピー割り当てできません。静的なサイズの配列(外側の次元が柔軟な場合)を並べ替える最も簡単な方法は、次を使用することstd::array<T, N>です。

std::array<int, 10> array[10];
std::sort(std::begin(array), std::end(array));
于 2012-12-18T01:11:55.867 に答える