0

Cのポインターについて学んでいます。ハッシュマップの次の構造体を使用しています。

struct hashLink {
   KeyType key; /*the key is used to look up a hashLink*/
   ValueType value; /*an int*/
   struct hashLink * next; /*these are like linked list nodes*/
};

struct hashMap {
    hashLink ** table; /*array of pointers to hashLinks*/
    int tableSize; /*number of buckets in table*/
    int count; /*number of hashLinks in table*/
};

コマンド ラインを使用して、「All's fair in love and in war.」などのテスト センテンスを含むファイルの名前をプログラムに指定します。ループを使用して、 を返す getWord というメソッドを使用しますchar* word。引き続きループ内で、hashMap、word、および値1を呼び出して insertMap() に渡します。

insertMap 関数は次のとおりです。

void insertMap (struct hashMap * ht, KeyType k, ValueType v)
{
    int idx;
    idx = stringHash(k) % ht->tableSize; //hash k to find the index

    if (idx < 0) idx += ht->tableSize;

    if (containsKey(ht, k)) {  //check to see if k is already in the hash map
            ht->table[idx]->value++;  // if yes, increment value to reflect number of times a word appears in the sentence.
        }
    else {  // if k is not in the hashmap, create a new hashLink
        struct hashLink *newLink = (struct hashLink *)malloc(sizeof(struct hashLink));
        newLink->value = v;
        newLink->key = k;
        newLink->next = ht->table[idx];
        ht->table[idx] = newLink;
        ht->count++;
    }
}

これが問題です。これはチェーン付きのハッシュマップです。単語が 2 回目に渡されると、プログラムはそれを同じ単語として認識せず、ハッシュ マップに新しいリンクを作成します。たとえば、上記の文の例では、デバッガーを使用して、「in」の最初のインスタンスのキーが であることがわかります0x8f4d00 'in'。次のインスタンスは0x8f4db8 'in'. 明らかに、char* word正しく使用していません。insertMap asKeyType keyに渡されると、2 番目の "in" に対して新しい hashLink が作成されるためです。

私は多くのことを試しましたが、セグメンテーション違反が発生し始め、実際にダメージを与える前にやめたほうがよいと思いました:)。char* wordに渡す前に使用する方法についての提案があるためinsertMap()、単語へのポインターではなく、単語自体のみが渡されて保存されます。それとも、先に進んでポインターを渡す必要がありますが、現在とは異なる方法で処理する必要がありますか? ありがとう。

4

1 に答える 1

1

ポインターが指す値を比較する必要がありchar *wordますが、通常はポインター自体を関数に渡します。そこに到達したら、ポインタを逆参照して、メモリ内で何を指しているかを調べます。

たとえば、ハッシュマップのキーを と比較したい場合char *k:

strncmp(ht->table[i]->key, k, length);

これは非常に簡単に自分で行うことができます。

int compare_strings(char *s1, char *s2, int len)
{
  int i;
  for (i = 0; i < len; i++)
    if (*s1 != *s2)
      return 0;

  return 1;
}

上記の関数は、 と のlen文字を比較s1s2ます。これは単なる例です。通常、境界チェックを行い、渡されたポインターをテストします。

于 2013-03-10T03:55:00.220 に答える