2

私は C++ を勉強していて、配列 [n][m] を作成し、それを整数で埋めてから、
"Characteristic of matrix rows is called the sum of its positive even elements. You need to sort the rows of the matrix in accordance with the growth of characteristics."

それは私のコードです

#include "stdafx.h"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
srand((unsigned)time(NULL));

int n, m;
cout << "n = ";
cin >> n;
cout << "m = ";
cin >> m;

int ** mas = new int * [n];
for (int i = 0; i < n; ++i)
{
    mas[i] = new int[m];
}

cout << "Array:\n";
for (int i = 0; i < n; ++i)
{
    for (int j = 0; j < m; ++j)
    {
        mas[i][j] = rand()%41-20;
        cout << mas[i][j] << "\t";
    }
    cout << "\n";
}

double * characteristic = new double[n];
for (int i = 0; i < n; ++i)
{
    characteristic[i] = 0;
}

for (int i = 0; i < n; ++i)
{
    for (int j = 0; j < m; ++j)
    {
        if((j%2 == 0) && (mas[i][j] >= 0)) 
        {
                characteristic[i] += mas[i][j];
        }
    }
}

cout << "Characteristics:\n";
for (int i = 0; i < n; ++i)
{
    cout << characteristic[i] << " ";
}
cout << "\n";

for (int i = 0; i < n - 1; ++i)
{
    int min = i;
    for (int j = i + 1; j < n; ++j)
    {
        if (characteristic[min] <= characteristic[j]) continue;
        min = j;
    }
    if (min != i)
    {
        double temp = characteristic[i];
        characteristic[i] = characteristic[min];
        characteristic[min] = temp;

        for (int k = 0; k < m; ++k)
        {
            int temp1 = mas[i][k];
            mas[i][k] = mas[min][k];
            mas[min][k] = temp1;
        }

    }
}

cout << "\nSorted characteristics:\n";
for (int i = 0; i < n; ++i)
{
    cout << characteristic[i] << " ";
}
cout << "\n";

cout << "Sorted array:\n";
for (int i = 0; i < n; ++i)
{
    for (int j = 0; j < m; ++j)
    {
        cout << mas[i][j] << "\t";
    }
    cout << "\n";
}

for (int i = 0; i < n; ++i)
{
    delete [] mas[i];
}
delete [] mas;

delete [] characteristic;

system("PAUSE");
return 0;
}

特性用に別の配列を作成し、それと最初の配列を同時にソートしましたが、特定のタスクを達成するのに難しすぎる方法を使用したようです。多分他の方法がありますか?

4

3 に答える 3

3

「特性」と同じ順序を使用して、行列も並べ替えますか?

特性を計算する C++ スタイルのコードがあるとします。

std::vector<double> characteristic(n, 0.0);
std::transform(begin(mas), end(mas), begin(characteristic), sum_);

次に、それらを並べ替えることができます。

std::sort(begin(characteristic), end(characteristic));

または、実際にマトリックスをすぐに並べ替えることができます。

std::sort(begin(mas), end(mas), [&sum_](int_vec const& a, int_vec const& b) 
         { return sum_(a)<sum_(b); });

編集正しい「特性合計」を使用するようにすべてのバージョンを修正しました(名前はそのままです)、@Adamに感謝します

これを示す完全なプログラムは次のとおりです: See it Live on Coliru

#include <random>
#include <iostream>
#include <string>
#include <vector>

#include <cstdlib>
#include <algorithm>
#include <iterator>

using namespace std;

int main()
{
    typedef std::vector<int> int_vec;

    srand((unsigned)time(NULL));
    int n, m;
    cout << "n = ";
    cin  >> n;
    cout << "m = ";
    cin  >> m;

    std::vector<int_vec> mas(n, int_vec(m));

    for (auto& v : mas)
        std::for_each(begin(v), end(v), [](int& i) { i = rand()%41-20; });

    cout << "Array:\n";
    for (auto const& v : mas)
    {
        std::copy(begin(v), end(v), ostream_iterator<int>(cout, "\t"));
        cout << "\n";
    }

    auto sum_ = [m](int_vec const& v) { 
        double vchar = 0;
        for (auto j = 0; j < m; j+=2)
            if(v[j] >= 0) vchar += v[j];
        return vchar;
    };

    std::vector<double> characteristic(n, 0.0);
    std::transform(begin(mas), end(mas), begin(characteristic), sum_);

    cout << "Characteristics:\n";
    std::copy(begin(characteristic), end(characteristic), ostream_iterator<double>(cout, " "));
    cout << "\n";

    std::sort(begin(characteristic), end(characteristic));

    cout << "\nSorted characteristics:\n";
    std::copy(begin(characteristic), end(characteristic), ostream_iterator<double>(cout, " "));
    cout << "\n";

    std::sort(begin(mas), end(mas), [&sum_](int_vec const& a, int_vec const& b) { return sum_(a)<sum_(b); });

    cout << "Sorted Array:\n";
    for (auto const& v : mas)
    {
        std::copy(begin(v), end(v), ostream_iterator<int>(cout, "\t"));
        cout << "\n";
    }

}

出力例:

n = m = Array:
11  15  19  18  
-20 -16 2   -11 
8   2   19  8   
Characteristics:
30 2 27 

Sorted characteristics:
2 27 30 
Sorted Array:
-20 -16 2   -11 
8   2   19  8   
11  15  19  18  
于 2013-10-11T07:07:31.453 に答える
1

@sehe は素晴らしいアドバイスをくれますが、C++ をもっと理解するまで、その多くは意味をなさないと思います。

遅いループをなくすための簡単な改善を次に示します。

行スワップを行うときは、行ポインターが指すすべての値をコピーするのではなく、行ポインターを交換します。これを置き換えます:

    for (int k = 0; k < m; ++k)
    {
        int temp1 = mas[i][k];
        mas[i][k] = mas[min][k];
        mas[min][k] = temp1;
    }

と:

    int* temp1 = mas[i];
    mas[i] = mas[min];
    mas[min] = temp1;

これに加えて別の改善となる組み込みの並べ替えアルゴリズムの使用方法を理解できれば、この小さな変更でも多くのことが得られます。

于 2013-10-11T09:12:45.623 に答える
0

サイズ n,m はコンパイル時に既知であるためqsort、C ライブラリの関数を使用できます。

#include <stdlib.h>

void qsort(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *));

where iscomparは作成する関数であり、両方の引数を行列の行へのポインターとして扱う必要があります。次に、両方の行の特性を計算し、どちらの行の特性が大きいかに応じて、-1、0、または 1 を返します。

于 2013-10-11T06:54:26.463 に答える