1

配列をソートし、各値をその「スコア」またはランクに置き換える関数を C/C++ で作成しようとしています。これは、int の配列への double ポインター配列を受け取り、逆参照された整数の値に基づいて double ポインターをソートします。私はそれを機能させるためにかなりの回数を試みましたが、それを落とすことはできません。繰り返しになりますが、double ポインターは、それらが指す値に基づいてソートする必要があります。これは私が持っているものです:

void SortArray( int ** pArray, int ArrayLength )
{
  int i, j, flag = 1;     // set flag to 1 to begin initial pass
  int * temp;             // holding variable orig with no *
  for(i = 1; (i <= ArrayLength) && flag; i++)
  {
    flag = 0;
    for (j = 0; j < (ArrayLength -1); j++)
    {
        if (*pArray[j+1] > *pArray[j])    // ascending order simply changes to <
        { 
            temp = &pArray[j];            // swap elements
            pArray[j] = &pArray[j+1];
            pArray[j+1] = &temp;
            flag = 1;                     // indicates that a swap occurred.
        }
    }
  }
}
4

5 に答える 5

5

あなたは近くにいます。スワップ時に配列項目のアドレスを参照していますが、これは必要ありません。配列内の項目はポインターであり、それを交換する必要があります。

下記参照:

void SortArray( int ** pArray, int ArrayLength )
{
    int i, j, flag = 1;    // set flag to 1 to begin initial pass
    int * temp;             // holding variable orig with no *
    for(i = ArrayLength - 1; i > 0 && flag; i--)
    {
        flag = 0;
        for (j = 0; j < i; j++)
        {
            if (*pArray[j] > *pArray[j+1])      // ascending order simply changes to <
            { 
                temp = pArray[j];             // swap elements
                pArray[j] = pArray[j+1];
                pArray[j+1] = temp;
                flag = 1;               // indicates that a swap occurred.
            }
        }
    }
}

また、興味がある場合は、バブル ソーティングに関するこの素敵なブログ投稿もチェックしてください(申し訳ありませんが、恥知らずなプラグイン:))。あなたの宿題に役立つことを願っています;)


編集:配列の長さから逆算し、内側のループで「i」までしかインクリメントしない微妙な「最適化」に注意してください。これにより、すでにソートされているアイテムを不必要に再解析する必要がなくなります。

于 2008-08-20T01:53:47.837 に答える
3

へー、これは宿題じゃない。

その場合は、STL を使用して配列と並べ替えを管理することを検討してください。開発と保守が簡単で、std::sort アルゴリズムはバブル ソートよりも漸近的に高速です。

于 2008-08-20T02:08:49.593 に答える
2

std::swap()スワッピングを行うために使用することを検討する必要があります。その場合は、次のように呼び出します。

swap( obj1, obj2 );

それよりも:

std::swap( obj1, obj2 );

最初の呼び出しセマンティックにより、適切な名前空間ルックアップが存在する場合に正しいオーバーロードを見つけることができるようになります。次のいずれかを用意してください。

using namespace std;

また:

using std::swap;

どこか。

于 2008-08-20T02:12:01.927 に答える
1

うーん、私は STL の経験があまりありません。例を挙げていただけますか?

このプログラムは、int のベクトルを作成し、並べ替えて、結果を表示します。

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

int main()
{
    vector<int>; vec;
    vec.push_back(7);
    vec.push_back(5);
    vec.push_back(13);
    sort(vec.begin(), vec.end());

    for (vector<int>::size_type i = 0; i < vec.size(); ++i)
    {
        cout << vec[i] << endl;
    }
}
于 2008-08-20T14:04:48.437 に答える
0

Brian Ensinkの投稿を完了するには、STLが驚きに満ちていることがわかります。たとえば、std :: sortアルゴリズム:

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

void printArray(const std::vector<int *> & p_aInt)
{
   for(std::vector<int *>::size_type i = 0, iMax = p_aInt.size(); i < iMax; ++i)
   {
      std::cout << "i[" << static_cast<int>(i) << "] = " << reinterpret_cast<unsigned     int>(p_aInt[i]) << std::endl ;
   }

   std::cout << std::endl ;
}


int main(int argc, char **argv)
{
   int a = 1 ;
   int b = 2 ;
   int c = 3 ;
   int d = 4 ;
   int e = 5 ;

   std::vector<int *> aInt ;

   // We fill the vector with variables in an unordered way
   aInt.push_back(&c) ;
   aInt.push_back(&b) ;
   aInt.push_back(&e) ;
   aInt.push_back(&d) ;
   aInt.push_back(&a) ;

   printArray(aInt) ; // We see the addresses are NOT ordered
   std::sort(aInt.begin(), aInt.end()) ; // DO THE SORTING
   printArray(aInt) ; // We see the addresses are ORDERED

   return EXIT_SUCCESS;
}

配列の最初の印刷では、順序付けされていないアドレスが表示されます。2つ目は、並べ替え後、順序付けられたアドレスを表示します。私のコンパイラには、次のものがあります。

i[0] = 3216087168
i[1] = 3216087172
i[2] = 3216087160
i[3] = 3216087164
i[4] = 3216087176

i[0] = 3216087160
i[1] = 3216087164
i[2] = 3216087168
i[3] = 3216087172
i[4] = 3216087176

STLの<algorithm>ヘッダーを見てくださいhttp://www.cplusplus.com/reference/algorithm/ たくさんのユーティリティがあります。より適したコンテナの他の実装があることに注意してください(std :: list?std :: map?)。

于 2008-09-21T23:27:30.913 に答える