2

私は2文字の単語で辞書を作ろうとしていますが、あまり成功していません.これが私のコードです:

#include <cstdlib>
#include <iostream>
#include <map>
using namespace std;

int main(int argc, char *argv[]){
    map<char*,int> m;
    //input 5 two-lengthed words 
    for (int i=0;i<5;i++){
        char s[3];
        cin>>s;
        s[2] = '\0';
        m[s]=1; //add a key
    }
    //checking if a word exists.

    cout<<"Word you want to check whether it exists:"<<endl;
    char chck[3];
    cin>>chck;
    chck[2]='\0';
    //I heard this is how you check whether a key exists:
    bool exists = m.find(chck)==m.end(); 
    cout<<((exists)?"Yes!":"No.")<<endl;
    system("pause"); //Yea, system, I know.
    return 0;
}

単語を入力するたびに、単語が辞書に載っているかどうかを確認したいときに、常に「いいえ」と出力されますか? 私はJava
から来たので、ポインタではなく参照に慣れてしまったので、おそらく間違っているところです。地図の正しい使い方を知りたいので、ここで何をすればいいですか? ありがとう

4

3 に答える 3

6
//I heard this is how you check whether a key exists:
bool exists = m.find(chck)==m.end(); 

はい。ただし、要素が存在しない場合、条件は true です。vaviable を呼び出す必要がありますnotExists

bool notExists = m.find(chck)==m.end();

ここで、作品が存在するかどうかを確認するだけであれば、std::set<std::string>. 単語を何か他のものへの鍵にしたい場合は、 が必要std::map<std::string, SomeThingElse>です。

それらを忘れてくださいchar*。sを使用std::stringします。

于 2013-03-01T21:39:42.040 に答える
2
    m[s]=1; //add a key

「キーを追加」するたびに、実際には同じキーを持つ同じ要素を取得するだけです。キーは、入力された文字列の値ではなくs、配列のアドレスです。

コンテナーのサイズを出力してみると、1 つの要素が表示されます。

   std::cout << m.size() << '\n';

a をコンテナーに入れchar*てデフォルトの比較関数を使用すると、同じ文字列ではなく、同じポインターである場合にのみ等しいと比較されます。

 char s1[] = "foo";
 char s2[] = "foo";
 assert( s1 == s2 );   // FAILS!

文字列値をコンテナにプッシュするには、std::stringキーではなくキーを使用しますchar*

std::string s1 = "foo";
std::string s2 = "foo";
assert( s1 == s2 );   // passes

これにより、ポインターを比較し、配列が範囲外になり、マップにダングリングポインターが残るという問題全体が回避されます。

于 2013-03-01T21:53:12.220 に答える
2

コードを少し見てみましょう。

あなたが持っていstd::map<char *, int>ます。その最初の「char*」は、マップへのキーとして疑わしいものです。多くの場合、ポインターをキーとして格納することは、本当にやりたいことではありません。しかし、私たちは読み続けます。ループ内には、入力するローカル配列 s があります。次に、その変数を使用してマップにインデックスを付けます。マップのキーは char* であることを思い出してください。配列 s のアドレスは、すべてのループ反復で同じになる可能性があります。その結果、おそらく 1 つのアイテムだけをマップに配置し、s に配置した最新の値のみを保持します。しかし、待ってください、それは悪化します。ループが完了するとすぐに、 s は範囲外になり、マップに現在格納されているポインターを逆参照するのは未定義の動作になります (そのマップ内の唯一の要素へのキーとして) m.size() を出力します確認)。

std::map<std::string, int>これらの問題がすべて発生しないように、マップを再定義してください。

于 2013-03-01T21:53:38.390 に答える