2011-04-26 24 views
7

は、現在の文字列が原因設計上の制約に文字や数字を(含むことができますオーバーロード比較です演算子「無効な演算子は、<」

C++で、文字列を含む各オブジェクトに、オブジェクトのベクトルを並べ替えしようとしますこれはコンパレータを変更できるので必要です)。

現在のところ、オブジェクトのクラスがオーバーロードされているため、2つのオブジェクトが比較されるときに、それらのオブジェクトに含まれる文字列が比較されます。これはちょっとしたことですが、ソート操作(STLソートなど)を使ってオブジェクトを並べると、 "1"、 "4"、 "12"の3つの文字列が順番にソートされます"1"、 "12"、 "4"。 4は12より大きくなりますが、最も左の桁からの比較が始まるため、この「不正な」ソートが発生します。

私の最初の対応は、比較操作のオーバーロード方法を変更することでした。私は最初に私が比較していた文字列の長さをチェックします。文字列の内容が大きかったり小さかったりすると、それは兆候となります。

// overloaded comparision operators 
friend bool operator<(const nodeRecord & record1, const nodeRecord & record2){ 
    // we need to deal with strings of different lengths... 
    if(record1.comparator.length() < record2.comparator.length()) 
     return true; 
    else 
     return (record1.comparator < record2.comparator); 
} 

この操作の結果、実行時に「式:無効な演算子<」というメッセージが表示されます。

私は間違いをどこにしているのですか?ソート操作をどのようにしたいのかを正確に指示することができるように思えます。無効な場合でも、現在はオブジェクトを格納するベクトルを使用しています。 nodeRecordオブジェクトの初期化中に

コンパレータ:あなたは1個のコンパレータを使用し、その機能が少し賢くていないのはなぜ

nodeRecord(int fromNode, int toNode, int connectionCost, bool compareByCost = false){ 
    // take the provided stock information and insert it into the object 
    stringstream fromNodeSS; 
    fromNodeSS << fromNode; 
    this->fromNode = fromNodeSS.str(); 
    stringstream toNodeSS; 
    toNodeSS << toNode; 
    this->toNode = toNodeSS.str(); 
    this->connectionCost = connectionCost; 

    // set the comparator to our chosen comparision term 
    if (!compareByCost){ 
     this->comparator = this->fromNode; // we use from node in this case, since we build the tree outwards 
    } 
    else{ 
     stringstream ss; 
     ss << this->connectionCost; 
     this->comparator = ss.str(); // we use the connection cost in this case, to allow us to sort new connections 
    } 

    // set this as a non-null (active) record 
    this->nullRecord = false; 
} 
+0

コンパレータは何ですか?そのコードを投稿してください。 –

+0

コンパレータの定義を表示していただけますか? –

+0

@Mikeと@Mario - コンパレータは、nodeRecordオブジェクトの初期化中に初期化されます。これは上で見ることができます。 – BSchlinker

答えて

10

あなたの事業者は実質的に無効です。

オペレータ<は、並べ替えに使用できるようにするには、数学的なプロパティが必要です。 x < y => !(y < x)

はのはx = "b"y = "aa"を定義してみましょう。一つは反対称プロパティです。

  • x < y"aa""b"

ハムよりも劣っているので、"b"の長さは"aa"

  • y < xの長さよりも劣っているので?

    また、接頭辞が0の場合は、数字の定義が変わっていることにも注意してください。

    ああ、文字列を比較するのは数値を比較するよりも遅いです。

    私の持ち時間は?比較情報でノードを変更しないでください。実際の比較モードは、ノード自体内で何もしません。

    次に、2つの比較方法を作成します.1つはコストで、もう1つは原点で比較します。


    そして、元の問題に来て、どのようにソートされた["a", "b", "aa"]を検討コンパレータを書くには?

    あなたはほぼそこにいましたが、「長さ」の比較は不完全です。長さが異なる場合にのみ、実際の字句比較に戻る必要があるため、右辺の引数の長さが左辺の長さよりも小さい場合を忘れてしまいます。

    は、このように正しい形式は、2つの文字列を想定し、次のとおりです。

    bool compare(std::string const& lhs, std::string const& rhs) { 
        if (lhs.length() < rhs.length()) { return true; } 
        if (rhs.length() < lhs.length()) { return false; } // don't forget this 
        return lhs < rhs; 
    } 
    
  • +0

    ありがとう!私が忘れてしまった別の事件について私に思い出させた。 – BSchlinker

    0

    ?最初に数字を確認したら、strtol()またはatoi()のペアを作成し、結果を比較してください。

    それ以外の場合は、文字列の長さと非数値要件ごとの文字を比較してください。

    +0

    私は文字列をソートする方法と同じように文字列をソートできるようにしたい。例えば、「a」、「aa」、「b」のスティングは、「a」、「b」、「aa」の順にソートする必要があります。私が投稿した方法は、これを達成するために私が知っている唯一の方法です。 – BSchlinker

    +0

    @BSchlinker:私の答えを更新しました。 – wallyk

    +0

    残念ながら、これは私の問題を解決しません。同じエラーが発生します=( – BSchlinker

    1

    エラーをスローしていた次のコードセグメントが見つかりました。次に、オーバーロードされた操作がどのように機能しているかを考えました。ソリューション作業

    template<class _Ty1, class _Ty2> inline 
        bool _Debug_lt(_Ty1& _Left, _Ty2& _Right, 
         _Dbfile_t _File, _Dbline_t _Line) 
        { // test if _Left < _Right and operator< is strict weak ordering 
        if (!(_Left < _Right)) 
         return (false); 
        else if (_Right < _Left) 
         _DEBUG_ERROR2("invalid operator<", _File, _Line); 
        return (true); 
        } 
    

    が、これは(再びマシューM.​​が残したコメントへの感謝を修正)助けたすべての人に

    // overloaded comparision operators 
    friend bool operator<(const nodeRecord & record1, const nodeRecord & record2){ 
        // we need to deal with strings of different lengths... 
        if(record1.comparator.length() > record2.comparator.length() 
         && (record1.comparator.length() !=0 && record2.comparator.length() != 0)) 
         return false; 
        else if(record1.comparator.length() < record2.comparator.length() 
         && (record1.comparator.length() !=0 && record2.comparator.length() != 0)) 
         return true; 
        else 
         return (record1.comparator < record2.comparator); 
    } 
    

    感謝です!

    関連する問題