4

私は C++ プログラミングの初心者で、最近、いくつかの配列をソートするための mergesort メソッドを作成しました。私の個人的なテストでは、整数と倍精度で問題なく動作します。しかし、文字列をソートしようとすると、「セマティックの問題」エラーが発生し、かなり混乱しています。完全なコードは次のとおりです。

#include <iostream>
#include <string>
using namespace std;

template<typename T>
class Sorting{
public:
static void merge(T* a, int left, int mid, int right){
    int i=left; int j=mid+1; int k=0;
    T t[right-left+1]; //****************ERROR LINE

    for(;i<=mid && j<=right;k++){
        if(*(a+i)<=*(a+j)){
            t[k]=a[i];
            i++;
        }
        else{
            t[k]=a[j];
            j++;
        }
    }

    for(;i<=mid;i++,k++) t[k]=a[i];

    for(;j<=right;j++,k++) t[k]=a[j];

    for(i=0;i<k;i++) a[left+i]=t[i];
}

//Mergesort top-level function. Left is starting index, right is ending index
static void mergesort(T* a, int left, int right){
    if(left>=right) return;
    int mid=left+((right-left)>>1);
    mergesort(a, left, mid);
    mergesort(a, mid+1, right);
    merge(a, left, mid, right);
}
};


int main(){
const int len=5; 
string ss[len]={
    "Yep",
    "Nope",
    "5",
    "2.5",
    "Stackoverflow"
};
double ar[len]={4.2, 3, 5.6, -15, 0};

Sorting<double>::mergesort(ar, 0, 4); for(int i=0; i<len;i++) cout<<ar[i]<<endl;
Sorting<string>::mergesort(ss, 0, 4); for(int i=0; i<len;i++) cout<<ss[i]<<endl;
return 0;
}

そして、次のような「// * *ERROR LINE」でセマンティック エラーが発生しました。

Variable length array of non-POD element type 'std::__1::basic_string<char>'

このエラーは何について話しているのですか? コードをどのように変更すればよいですか?

4

2 に答える 2

6

エラー メッセージで、PODは単純な古いデータ型を指します。

std::vectorそれらのいずれかを使用できます。

   std::vector<T> t;
   t.resize (right-left+1);

tポインターの配列を作成することもできます (つまりT* t[right-left+1];、それに応じてコードを更新します)。

ところで、可変長配列を使用しています。これは、他の一部のコンパイラが提供していないGCC 拡張機能です。

ただし、ソートは C++ 標準ライブラリで利用できます。標準 C++ コンテナーではstd::sort#include<algorithm>を使用する必要があります。

于 2013-06-10T05:12:04.020 に答える
6

可変長配列があります:

T t[right-left+1];

これは特定のコンパイラでサポートされている拡張機能であり、C++ 標準の一部ではありません。のような複雑なオブジェクト タイプでは機能しないstd::stringため、エラー メッセージが表示されます。次のように置き換えることができますvector

std::vector<T> t(right - left + 1);

ただし、ポインターを使用するという Basile のアイデアの方が優れていstd::stringます。オブジェクトをコピーするのはかなり重いです (つまり、メモリを集中的に使用し、低速です)。移動する要素を追跡したいだけでa[]、コピーを並べ替えてからコピーして戻すのではありません。

于 2013-06-10T05:13:10.057 に答える