0

次のコードがマージソートを行わない理由を理解しようとしています。コードは正常にコンパイルされ、実行時エラーは発生しません。SortCollectionメソッドは、ソートされていない配列を返すだけです。コンパイルエラーや実行時エラーはなく、ソートされていない配列を返すだけです。どんなポインタも大いに評価されるでしょう。

#include "stdafx.h"
#include <deque>
#include <climits>
#include <stdio.h>

using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;

generic <typename T> where T: IComparable<T>
ref class MergeSort
{
public:
// constructor
MergeSort(){}

// SortCollection() method
array<T>^ SortCollection(array<T>^ inputArray)
{
    int n = inputArray->Length;
    if (n <= 1)
    {
        return inputArray;
    }
    array<T>^ array1 = gcnew array<T>(inputArray->Length / 2);
    array<T>^ array2 = gcnew array<T>(inputArray->Length - array1->Length);
    int array1Count = 0;
    int array2Count = 0;
    for (int i = 0; i < n; i++)
    {
        if (i < n / 2)
        {
            array1[array1Count] = inputArray[i];
            array1Count++;
        }
        else
        {
            array2[array2Count] = inputArray[i];
            array2Count++;
        }
    }
    SortCollection(array1);
    SortCollection(array2);
    array<T>^ newArray = gcnew array<T>(inputArray->Length);
    delete inputArray;
    return Merge(newArray, array1, array2);
}

array<T>^ Merge(array<T>^ targetArray, array<T>^ array1, array<T>^ array2)
{
    int n1 = array1->Length;
    int n2 = array2->Length;
    int x1 = 0;
    int x2 = 0;
    int counter = 0;
    while (x1 < n1 && x2 < n2)
    {
        if (array1[x1]->CompareTo(array2[x2]) < 0)
        {
            targetArray[counter] = array1[x1];
            x1 ++;
            counter++;
        }
        else
        {
            targetArray[counter] = array2[x2];
            x2 ++;
            counter++;
        }
    }
    while (x1 < n1) 
    {
        targetArray[counter] = array1[x1];
        counter ++;
        x1 ++;
    }
    while (x2 < n2) 
    {
        targetArray[counter] = array2[x2];
        counter ++;
        x2 ++;
    }
    return targetArray;
}
};
4

2 に答える 2

0

ここに問題があります:

SortCollection(array1);              // array1 is deleted??
SortCollection(array2);              // you dont use any result from here?
array<T>^ newArray = gcnew array<T>(inputArray->Length);
delete inputArray;                   // sort, deleted input array !
return Merge(newArray, array1, array2);

ここは正しいですか?

array1=SortCollection(array1);                
array2=SortCollection(array2);          
array<T>^ newArray = gcnew array<T>(inputArray->Length);
delete inputArray;                     
return Merge(newArray, array1, array2);
于 2013-02-16T21:28:06.990 に答える
0

うーん...でも、何を印刷/テストしていますか?元の配列またはどのような並べ替えが返されますか?とにかく、これを試してください:

SortCollection(array1);                
SortCollection(array2);          
// array<T>^ newArray = gcnew array<T>(inputArray->Length);
// delete inputArray;                 ---> "reuse" the input array        
return Merge(inputArray, array1, array2);

編集:あなたはこれを知っていると確信していますが、あなたはそれにもっと注意を払う必要があります。

「通常の」関数は引数を取り、引数を変更せずに結果を返します。

Y=f(x);

x以前と同じであることが期待され、結果は。になりyます。これらは良い機能です。ただし、一部の関数は引数を変更します。いつかそれは明らかです

Destroy(x); 

しかし、多くの場合、のようにあまり明白ではありません

y=sort(x);

「値による」の受け渡しxは変更されないことを保証しますが、関数が一種の参照(のようなtype^ x)を取る場合、元の変数に直接アクセスでき、その内容を変更できます。この二重性はあなたが持っているものです(inSortCollectionとin Merge)。関数が何を返すか、および関数が取る引数をどのように変更するかを決定し、「文書化」する必要があります。

1つのバージョン(を使用delete)では、引数を変更して削除します!!! これは通常、良い考えではなく、非常に適切に文書化する必要があります。そして、ソートされた配列は「戻り値」として渡されます(実際には一種の参照でもあります)。このバージョンは引数を変更しますが、結果は返されます(そしてそれはあなたが使用/テスト/印刷する必要があるものです)。

削除のないバージョンは、ソートされた配列を引数に入れることにより、引数を変更します。この場合、それは完全にあなたが望むものである可能性があります。とにかく–それを文書化してください!ソートされた配列への参照、-引数への参照も返します。これは便宜上行われていますが、読みやすくするために除外することができ、「リターン」は無効になります。

3番目のバリアントは、引数を変更せずに、ソートされた配列を返すことです。

于 2013-02-17T00:02:14.873 に答える