6

さて、私は一種のハッシュテーブルとして機能する簡単な小さなクラスを作ろうとしています。私がそれを機能させることができれば、私はこれを行うことができるはずです:

  StringHash* hash = new StringHash;
  hash["test"] = "This is a test";
  printf(hash["test"]);

そして、「これはテストです」と出力されるはずです。

この時点で2つの問題があるようです。まず、私はこれをしました:

const char* operator[](const char* key) {
  for(int i = 0; i < hashSize; ++i) {
    if(strcmp(hkeys[i], key) == 0) {return values[i];}
  }
  return NULL;
}

しかし、値を調べようとすると、コンパイラは不平を言います

エラー: 配列添え字の無効な型 `StringHash*[const char[5]]'

第 2 に、operator[]= はここでは正しい構文ではないようです。他に見つけたのは &operator[] だけでしたが、ルックアップ手順をコーディングしなければならないので、うまくいかないと思いますか??? (その構文は、配列項目の参照を返すために使用されているだけではありませんか?)

私がここでやろうとしていることは可能ですか?アドバイスをいただければ幸いです。:)


私がやろうとしていることについて混乱しているようです。私は自分のコードを投稿します:

http://pastebin.com/5Na1Xvaz


すべてのヘルプの後の完成品:

http://pastebin.com/gx4gnYy8

4

8 に答える 8

6

エラーはhashポインタであるためです。への変更:

StringHash hash;
于 2010-10-11T14:13:07.440 に答える
4

他の答えはあなたの最初の質問に関連しています。あなたの2番目は...

参照を返す場合は、左辺値を返します。左辺値にはいつでも割り当てることができます。

はい、それは(ほとんど)本当に簡単です。constただし、いろいろな場所で必要かどうかをよく読んでおくことをお勧めします。

私が読んだことを覚えているのは、次のようなものに対して、constおよび非constオーバーロードを提供する必要があるということです。operator[]

MyType const &operator[](int index) const; // This is the array access version (no assignment allowed), which should work on const objects
MyType &operator[](int index);      // This is the array access or assignment version, which is necessarily non-const.

詳細については、このリンクを参照してください。

于 2010-10-11T14:19:48.283 に答える
3

hashStringHashオブジェクトではありません。1へのポインタです。

あなたはこれを行うことができます:

(*hash)["test"] = "This is a test";

または、そもそもなぜポインタが必要なのかを自問することもできます。

StringHash hash;
hash["test" = "This is a test";

...または、そうする場合でも、のようなスマートポインターを使用しないのはなぜですかauto_ptr

#include <memory>
std::auto_ptr<StringHash> hash( new StringHash );
(*hash)["test"] = "This is a test";
于 2010-10-11T14:14:28.697 に答える
2

最初に、標準のバージョンではなくても利用可能なバージョンがいくつかあるのに、なぜ独自の HashMap を作成しているのか疑問に思います。

ハッシュマップは const char* ポインターまたは std::strings を格納しますか? (それが寿命を変更しない別の場所に保存されたデータへの単なるルックアップ テーブルである場合は、const char * ポインターを保存する可能性があります)。

アイテムが見つからない場合、operator[] は何をすべきでしょうか?

- はい、const char * ポインターを格納しており、空のセルに NULL を格納しています - hash[key]=value を実行するとき、キーを値に関連付けたい - そのままの場合hash[key] 書き込みませんが、挿入しません

これは魔法のオブジェクトで行うことができます: const char * をこのオブジェクトに割り当てると、ハッシュに挿入または上書きされます。読み取りのために、オブジェクトから const char * への暗黙的な変換を行うこともできます。

これは非常に複雑ですが、map の通常のインターフェースに固執することをお勧めします。

于 2010-10-11T14:35:19.807 に答える
2

StringHash hash;物の代わりに書くnew。C++ は Java ではありません。:-)

于 2010-10-11T14:14:58.993 に答える
2

最初のエラーは、ハッシュをポインターとして宣言したことです。ポインター型は、既にインデックス演算子で使用できます。たとえば、pointer[3] は *(pointer+3) と同等です。その振る舞いを変えることはできません。オブジェクト自体をハッシュ化します。

StringHash sh;

operator[]= に関しては、そのようなことはありません。インデックス演算子は、割り当てを機能させるために参照を返す必要があります。これがどのように見えるかの簡単な例を次に示します。

class Indexable
{
   std::string arr[3];
public:
   std::string & operator[](int index) {
      return arr[index];
   }
   std::string const& operator[](int index) const {
      return arr[index];
   }
};
于 2010-10-11T14:23:06.620 に答える
2

5 つの問題:

  1. hashは StringHash へのポインターです。演算子を使用するには、逆参照する必要があります。(*hash)["test"]
  2. 要素に割り当てたい場合は、要素タイプへの参照を返す必要があります

    const char *& operator[] (const char* key);

    // ...

    (*hash)["test"] = "This is a test"; // will compile now

  3. nullは C++ のキーワードではありません。0 または を使用しますNULL

  4. operator []要素が見つからない場合は、要素にスペースを割り当てる必要があります。戻るNULLという選択肢はありません。そうしないと、結果に代入しようとすると(*hash)["test"]、プログラムがクラッシュします。
  5. 独自の「クイック」クラスを作成する代わりに、std::map または std::tr1::unordered_map を使用してください。

冗談ですが、これはハッシュ テーブルではないことをご存知でしょうか。

于 2010-10-11T14:23:48.617 に答える
1

を使用できますboost::unordered_map<std::string, std::stringか? そうすれば、これを自分で実装することを心配する必要はありません。

それがあなた自身のためのある種の演習であると仮定すると: あなたは異なるバックグラウンドから来たかもしれませんが、C++ ではハッシュを宣言する通常の方法は次のようになります:

StringHash hash;

さらにoperator[]、印刷物では機能する可能性がありますが、課題では機能しません。通常operator[]、メソッドは非 const 参照または新しい値を割り当てることができるプロキシ オブジェクトを返すことで機能しますが、あなたのメソッドはどちらも行いません。std::string を使用できた場合は、読み取りまたは割り当てが必要なハッシュ内の位置への非 const 参照を返すようにメソッドを書き直すことができます。

于 2010-10-11T14:26:26.907 に答える