0

私はこのミッションの第 2 部で立ち往生しています。私のアルゴリズムに問題があると思います。私のコードが良い方向にある場合はお知らせください。これが私のメッセージです 与えられた 2 次元整数の集合。配列は 5 行 10 列で構成されます。システム内の各値は、0 から 20 までの乱数です。配列値の並べ替えを実行するプログラムを次のように作成する必要があります。まず、各列の値を並べて、昇順 (上から下) に並べ替えます)、次に、同じ行の異なる列の値のペアを比較することにより、列を右に並べ替えることができます (「比較辞書編集」): 最初の行の 2 つの列の 2 つの値を比較します。 2 行目の値と比較して同じであるなど、それに応じて列の順序を変更します (以下の配列の 3 番目の印刷の例を参照してください)。並べ替え前と緊急事態の 2 つのフェーズのそれぞれの後にアレイを表示します。例えば ​​: 出力

 #include "stdio.h"
#include "conio.h"
#include "malloc.h"
#include "stdlib.h"

#define N 5
#define M 10
#define LOW 0
#define HIGH 20

void initRandomArray(int arr[N][M]);
void printArray(int arr[N][M]);
void SortInColumn(int arr[N][M],int m);
void SortColumns(int arr[][M]);
int compareColumns(int arr[][M], int col1, int col2);
void swapColumns( int col1, int col2);

int main()
{
    int arr[N][M];
    int m;
    m=M;

    srand((unsigned)time(NULL)); //To clear the stack of Random Number
    initRandomArray(arr);
    printf("Before sorting:\n");
    printArray(arr);
    printf("Sorting elements in each column:\n");
    SortInColumn(arr,M);
    printf("Sorting columns:\n");
    SortColumns(arr);

    system("pause");
    return 0;
}
void initRandomArray(int arr[N][M])
{

    int i,j;
    for (i=0 ; i<N ; i++)
        for (j=0 ; j<M ; j++)
        {
         arr[i][j]=LOW+rand()%(HIGH-LOW+1);
        }

}
void printArray(int arr[N][M])
{ 
    int i,j;
    for (i=0 ; i<N ; i++)
    {
        for (j=0 ; j<M ; j++)
            printf("%d ", arr[i][j]);
         printf("\n");
    }
}
void SortInColumn(int arr[][M],int m)
{

    int i,j,k;
    int temp;

    for( k=0 ; k<m ; ++k) // loops around each columns
    {
        for(j=0; j<N-1; j++)// Loop for making sure we compare each column N-1 times since for each run we get one item in the right place
        {
                for(i=0; i < N-1 - j; i++) //loop do the adjacent comparison
                {
                        if (arr[i][k]>arr[i+1][k]) // compare adjacent item
                        {
                                temp=arr[i][k];
                                arr[i][k]=arr[i+1][k];
                                arr[i+1][k]=temp;
                        }
                }
        }
    }

    printArray(arr);
}
void SortColumns(int arr[][M])
{   int row=0,cols=0,i=0,n=N;
    int col1=arr[row][cols];
    int col2=arr[row][cols];
    compareColumns(arr,col1,col2);

}
int compareColumns(int arr[][M], int col1, int col2)
{
    int row=0,cols=0,j;
    for ( row=0 ; row < N ; row ++ );
        {
            for( cols=0 ; cols < M-1 ; cols++)
            {
                if(arr[row][cols]>arr[row][cols+1])
                {
                  for (j=0 ; j < M-1 ; j++)
                  {
                    col1=arr[row][cols];
                    col2=arr[row][cols+1];
                    swapColumns(col1 , col2 );
                  }

                }
            }
        }
    printArray(arr);
}
void swapColumns(int col1, int col2)
{
    int temp;
    temp=col1;
    col1=col2;
    col2=temp;

}

ところで、compareColumns 関数の Complexity は (n^3) ですか?

4

1 に答える 1

0

そのアルゴリズムは遅すぎます。もっとうまくやることができます。

すべての数値が 0 から 20 の間にあるという事実を利用して、列を線形時間で並べ替えることができます。これを行うには、補助的な 20x10 配列を使用します。ここで、array[i][j] は、値 i が元の行列の列 j に表示される回数を保持します。あなたの例では、最初の列には値 12、18、13、17、13 が含まれているため、次のようになります。

配列[12][0] = 1

配列[13][0] = 2

配列[18][0] = 1

配列[17][0] = 1

この配列の作成には、n 個の要素を持つ行列の場合、O(n) 時間かかります (実際、問題のサイズは常に同じです - 5*10 = 50)。

そのアレイを構築した後、次の 2 つの可能性があります。

a) ソートされた列の値で元のマトリックスを上書きします。このために、補助配列の各列 j に移動し、値をスキャンします。たとえば、最初の列の場合、最初のゼロ以外の値は配列 [12][0] にあり、これは 1 であるため、元の配列の最初の列に「12」を書き込み、行数をインクリメントして次のようにします。次の値を正しい位置に書き込みます。次に、array[13][0] が 2 であることがわかるので、元の行列に "13" を 2 回書きます。すべての列に対してこれを続けます。これで、列が並べ替えられた行列ができました。この方法を列間の辞書式並べ替えに適用できます。

b) 列間で辞書式の順序が必要なため、これは累積合計値で列を並べ替えるのと同じであることがわかります。したがって、10 要素の別の追加配列を格納できます。各要素は、array[0..20][j] の累積合計と位置 j を保持する構造体です (位置 i については、array[i][ j]*i は合計の実際の値です)。この 10 要素の配列の並べ替えは非常に高速です。あとは、この並べ替えられた配列を反復処理するだけです。その配列の各位置について、元のインデックス j (以前に構造体に格納されていた) を使用して配列 [0][j] にインデックスを付け、次に a) で説明した方法を使用して元の行列を上書きします。これには、ソート手順をまったく記述する必要がないという利点があります。システムの qsort を使用できます。

このソリューションは、許容値に対して適切にスケーリングされます。N 要素の行列の場合、補助配列と累積和配列の構築には O(N) かかります。累積合計配列のソートには、列数に比例して時間がかかり、元の配列の上書きには O(N) 時間がかかります。

このアルゴリズムは十分に高速ですが、非常に大きな値に対して大量のメモリを消費する可能性があることに注意してください。ランタイムを増やすことでメモリ使用量を削減できるかどうかを検討することをお勧めします。

あなたが投稿したコードは非常に不完全です。もう少し洗練されたものを提供してください。

于 2013-09-19T10:24:38.993 に答える