• ベストアンサー

c言語でハッシュを作るらしいのですが...

c言語でハッシュを作るんですが、勉強不足のためいまいち理解が追いついていないのが現状です。昔の字体を、今の字体に変換するために下記の記述のあるファイル読み込むんですが、この2,3列目が昔の字体で、この文字があったら1列目の今の字体へのポインタを返すように配列に入れたいんです。誰かやり方をおしえてくれませんか?、 没,沒,歿 壱,壹,弌 奇,竒,綺 協,恊,叶

質問者が選んだベストアンサー

  • ベストアンサー
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.3

どうもよくわかりません。この場合にハッシュを使うなら、 1.旧字体の文字コードより、ハッシュキーを作成 2.ハッシュキーより、検索用テーブルを選択 3.検索用テーブルを使って実際の検索 という流れになると思うのですが、わからないのはどのあたりなのでしょうか?

yxia001
質問者

補足

最初の1番からです。ハッシュの作成がよくわからないんです。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.5

>ハッシュはこんな感じで作ろうというイメージはあるのですが、具体的にプログラムをどうすれば、ハッシュを作れるかをまだつかめていないのです だから、まずはハッシュキーを作ります。 ハッシュキーというのは、単に検索テーブルを選択するだけの値ですから、0~(検索テーブル数-1)の値をとります。 なので、検索テーブルを256個にするなら、それこそ、文字コードの下位1バイトでも十分です。

yxia001
質問者

補足

すいません。まだ、よく意味がわかりません。調べてみます。

全文を見る
すると、全ての回答が全文表示されます。
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.4

>最初の1番からです。ハッシュの作成がよくわからないんです。 それは、 >ハッシュの作り方としては、旧字体を文字コードにして数字とみなし、その数字を最大値よりも大きい素数で割ってその数字でハッシュを作ろうと考えています。 と、書かれていましたので、わかってらっしゃるのかなと思ったのですが。どこがわからないのでしょうか?

yxia001
質問者

補足

>ハッシュの作り方としては、旧字体を文字コードにして数字とみなし、その数字を最大値よりも大きい素数で割ってその数字でハッシュを作ろうと考えています。 ハッシュはこんな感じで作ろうというイメージはあるのですが、具体的にプログラムをどうすれば、ハッシュを作れるかをまだつかめていないのです。

全文を見る
すると、全ての回答が全文表示されます。
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

>旧字体から新字体へぶつけ方は旧字体を一列の配列にいれ、検索する字体を、旧字体を入れた配列に全件検索して見つけていく感じです。 ハッシュというのは、つまり、その検索用の配列が非常に大きくなった場合に、配列を分割するための手法です。1Mバイトの検索用配列も256個に分割すれば、一つ一つは256Kバイトから検索すればいいので、高速化になります。 そして、この分割方法(=ハッシュキーの作り方)次第でどの程度高速化されるのかが違ってきますので、このあたりが工夫のしどころだったりします。

yxia001
質問者

補足

ハッシュの作り方としては、旧字体を文字コードにして数字とみなし、その数字を最大値よりも大きい素数で割ってその数字でハッシュを作ろうと考えています。 ハッシュのバイト数を指定してchar型のポインタとint型で作ろうとしています。

全文を見る
すると、全ての回答が全文表示されます。
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.1

なにがわからないのでしょうか? 1.ファイルの読み方 2.旧字体から新字体の検索のしかた 3.ハッシュの作り方 「全部わからない」というなら、上から順番に。ハッシュというのは、高速化すための手法なので、とりあえずはあとまわしにしても問題ありません。 ファイルがUNICODEなのかSJISなのかも非常に重要な点ですので、押さえておきましょう。

yxia001
質問者

補足

コードはutf=-8です。ハッシュというものが検索に向いているという大まかな知識しか知らず、しっかりとどういう挙動をするのかは、捕らえていないです。 旧字体から新字体へぶつけ方は旧字体を一列の配列にいれ、検索する字体を、旧字体を入れた配列に全件検索して見つけていく感じです。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • c言語でcsvファイルを配列に入れたいのですが

    新旧字体の対応表が入っているcsvファイルを読み込んで配列に入れて操作したいんです。以下のような表です。 伝,傳,傅 没,沒,歿 壱,壹,弌 奇,竒,綺 協,恊,叶 画,畫,劃 界,畍,堺   : これは旧字体が2つあるもので行数は59あります。このほかにも旧字体が1から9までの表がそれぞれあるのですが、これを配列に入れて旧字体を1列に並べ、その横にその旧字体の新字体を並べる操作をしたいんです。 傳,伝 傅,伝 沒,没 歿,没 壹,壱 弌,壱 : こんな感じにしたいんですが、csvファイルを配列に入れるところからこんがらがっています。 誰かご教授願えませんか?

  • C言語

    今、独学でC言語を勉強しているんですが。 大きく、 条件処理、繰り返し処理、配列、関数、2次元配列、文字列、構造体、ファイル処理、乱数、検索、バブル・ソート、ポインタ まではやったんですが(参考書で勉強)。 その次になにを勉強したらよく分からないので、 何を勉強するべきか教えてください。 将来的にこれっと言った作りたいものは決めていません。 お願いします。

  • c言語 ハッシュ表

    下のハッシュ表のプログラムについて質問です.関数enterを二回呼び出して,valueの値を変更して表示させても値が更新されません.値が更新せれるにはどうすればよいのでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASH_SIZE 997 /* ハッシュ表の内部配列のサイズ */ #define HASH_RADIX 97 /* ハッシュ関数用の基数 */ /* ハッシュ表内の連結リストに含まれるノードの構造体 */ struct hash_node { /* ハッシュ表内の連結リストのノード */ char *key; /* キー */ int value; /* キーに対応する値 */ int id; /* キーに付与された通し番号 */ struct hash_node *next; /* 次のノードへのポインタ */ }; typedef struct hash_node HashNode; typedef HashNode *HashNodePtr; /* ハッシュ表の構造体 */ struct hashtable { HashNodePtr *heads; /* 内部配列 */ int serial_id; /* 通し番号管理用の変数 */ int size; /* 内部配列のサイズ */ }; typedef struct hashtable HashTable; typedef HashTable *HashTablePtr; /* 文字列 s のハッシュ値を計算する */ unsigned int hash(char *s) { unsigned int v; v = 0; while (*s != '\0') { v = v * HASH_RADIX + *s; s++; } return v; } /* ハッシュ表を一つ生成し,そのポインタを返す */ HashTablePtr create_hashtable() { HashTablePtr t = NULL; int i; t = malloc(sizeof(HashTable)); t->serial_id = 0; t->size = HASH_SIZE; t->heads = malloc(sizeof(HashNodePtr) * t->size); /* 各連結リストの先頭要素へのポインタは必ず NULL に初期化する */ for (i = 0; i < t->size; i++) { t->heads[i] = NULL; } return t; } /* 指定したポインタ変数に NULL を代入して終わるためのマクロ */ #define delete_hashtable(t) \ (delete_hashtable0(t),t=NULL) /* 実質的な削除作業を行う関数(free 後の NULL 代入は省略)*/ void delete_hashtable0(HashTablePtr t) { HashNodePtr n = NULL, m = NULL; int i; /* 各連結リストの領域を解放 */ for (i = 0; i < t->size; i++) { n = t->heads[i]; while (n != NULL) { m = n; n = n->next; free(m); } } /* 最後に連結リストの先頭ポインタの領域を解放 */ free(t->heads); free(t); } /* ハッシュ表 t に登録されているキーと値のペアの数を返す */ int get_cardinality(HashTablePtr t) { return t->serial_id; } /* ハッシュ表 t にてキー key に対応する値を調べる */ int lookup(HashTablePtr t, char *key) { HashNodePtr n = NULL; int index; /* ハッシュ表の内部配列の添え字を計算 */ index = hash(key) % t->size; /* index 番目の連結リストを先頭から順に走査 */ n = t->heads[index]; while (n != NULL) { /* 引数で指定された key とハッシュ表内のキーが一致したら 直ちに対応する値を返す */ if (strcmp(key, n->key) == 0) return n->value; /* 走査を次に進める */ n = n->next; } /* ここではキーに対応する値は非負であると仮定し, 見つからなかったら -1 を返す */ return -1; } /* キー key と値 value のペアをハッシュ表 t に登録し,その通し番号を返す */ int enter(HashTablePtr t, char *key, int value) { HashNodePtr n = NULL, m = NULL; int index; index = hash(key) % t->size; /* 内部配列の添え字を計算 */ /* キーが既に存在しているかどうかチェック(lookup() と同じ処理)*/ n = t->heads[index]; while (n != NULL) { if (strcmp(key, n->key) == 0) return n->id; /* 通し番号を返す */ n = n->next; } /* 新しいノードを生成 */ m = malloc(sizeof(HashNode)); m->key = _strdup(key); m->id = t->serial_id; m->value = value; /* 連結リストの add_first() と同様にして連結リストに追加 */ m->next = t->heads[index]; t->heads[index] = m; t->serial_id++; /* 次の通し番号に更新 */ return m->id; /* 登録したキーと値のペアに付与された通し番号を返す */ } /* * ハッシュ表 t に登録されるキーの配列を返す *(この配列のサイズは get_cardinality() で取得可能) */ char **get_keys(HashTablePtr t) { char **keys = NULL; HashNodePtr n = NULL; int i; keys = malloc(sizeof(char *) * t->serial_id); /* 各連結リストを走査し,配列に詰め込む */ for (i = 0; i < t->size; i++) { n = t->heads[i]; while (n != NULL) { keys[n->id] = n->key; /* 通し番号を配列添え字に */ n = n->next; } } return keys; /* 後で free() する必要あり */ } void print_hashtable(HashTablePtr t) { printf("Taro => %d\n", lookup(t, "Taro")); } /* ハッシュ表の使用例 */ int main(void) { HashTablePtr t = NULL; t = create_hashtable(); enter(t, "Taro", 25); print_hashtable(t); enter(t, "Taro", 35); print_hashtable(t); delete_hashtable(t); }

  • C言語でゲーム

    今、独学でC言語を勉強しているんですが。 大きく、 条件処理、繰り返し処理、配列、関数、2次元配列、文字列、構造体、ファイル処理、乱数、検索、バブル・ソート、ポインタ を勉強したんですが。 もしも、ゲームを作るとしたら・・ もし、ボンバーマンみたいなのを作るとなるとどういう勉強をすればいいんでしょうか? もうひとつはHALOみたいなxbox関係などはどの様な勉強をすればいいんでしょうか? 質問が多いですが、よろしくお願いします。

  • 文字列をハッシュにしなければならないのですが

    C言語にさ ファイルの中にある、3バイトunicodeの漢字文字列郡をハッシュテーブルに格納してハッシュを作りたいんですが、取っ掛かりすらつかない状況です。 とりあえず、配列から3バイトの16進数にして、後はその文字列分の16進数を足して、それを割ってキーをつくりテーブルにいれる、としようとしています。 配列から3バイトの16進数にする int joint(char a, char b, char c){ int join = 0; join = a<<8; join = (0x0000FF00 & join) + (0x000000FF & b); join = join<<8; join = (0x00FFFF00 & join) + (0x000000FF & c); return join; } このように16進数にするのですが、最初の取っ掛かりとしてのハッシュについては、どうやったらハッシュテーブルに格納でくるのかいまいちわからないのです。誰かわかりやすく教えてください。

  • C言語に関することについて教えてください

    学校の問題集にでてきた問題がわかりません、どうか教えてください 1 プログラムの役割、必要性について説明せよ 2 プログラムにおける変数と定数の役割を説明せよ。また、ローカル変数の有効な範囲について説明せよ。 3 C言語で使う変数が他について、宣言子と、printf関数、scanf関数それぞれにおいて対応する書式指定子を対応表にせよ。また、変数名を決める際に守るべき文法上の規則と、プログラマとして配慮すべき事項を説明せよ。 4 配列について、その役割と定義方法を説明せよ。 5 コンピュータにおける文字処理に必須なアスキーコードについて説明せよ。 6 C言語における文字列について、文字列定数、文字列変数を説明せよ。 7 C言語における繰り返し処理の文法(for,while,do~while)を、プログラムコード列を示して説明せよ。 8 C言語における条件判断の文法(if,else,else if)を、プログラム列を示して説明せよ。 9 繰り返し、条件判断において利用する論理式(等値演算子、関係演算子、論理演算子等で記迷する式)について、その記迷の方法を論理和、論理積も含めて説明せよ。 10 変数のアドレスについて説明せよ。また、ポインタについて、アドレスとの関連性を踏まえて、その役割と定義方法を説明し、具体的な使い方のプログラムコード例を示せ。 11 ポインタと配列の関係について、ポインタによる配列操作を列に説明せよ。 12 関数について、その役割と定義方法について説明せよ(戻りがた、関数名、引数リスト)。また、自作関数をそれらを利用するmain関数のプログラムコード例を示せ。 13 scanf関数の戻り値について、その内容を説明して、どのような際に利用すると便利か、プログラムコード例を示して説明せよ。 14 引数にポインタを利用する関数のプログラムコード例を示して、ポインタの必要性、重要性を説明せよ。 15 構造体について、その役割と定義方法を説明し、具体的な使い方のプログラムコード例を示せ。 16 ファイルポインタについて説明し、ファイル入出力の方法についてプログラムコード例を示して説明せよ。

  • C言語に関する質問

    C言語を独学で学んでいる者です。 配列に10桁の文字を格納して、そこから任意の1文字を探し出す(何番目に何の文字があると表示する)プログラムを作ってみたいのですが、どのように記述したらよいか分かりません。特に、10桁の文字列に同じ文字が複数含まれる場合は完全にどうしたら良いのかわからない状態です。 お分かりの方は、ぜひご教授願います。

  • C言語

    以下のC言語のプログラムを教えてください。 お願いします。 (1)標準入力から文字列(2 文字以上)を入力し,文字数を計上すると共に,入力された文字列の逆順に入れ替える処理を実現してください.なお,以下の要件を満たしたプログラムを作成してください. ・ 入力された文字列は,char 型の配列(要素数50)で受け取ること ・ 文字数を計上するcount 関数(引数:配列のアドレス,戻り値:文字数)を定義 し,main 関数より呼び出すこと ・ 文字列を逆順に入れ替えるreverse 関数(引数:配列のアドレス,戻り値:無し) を定義し,main 関数より呼び出すこと ・ 標準出力の処理は,main 関数で記述すること 【プロトタイプ宣言】 int count(char *str); void reverse(char *str); 【実行結果】 文字列を入力してください(2 文字以上) apple 文字数 = 5 入れ換え前 apple 入れ換え後 elppa (2)char 型の配列(要素数50)を2 つ宣言し,標準入力から2 つの文字列を入力してください.そして,格納した字列を入れ替える関数(swapstr 関数)を作成し,入れ替え前と入れ替え後の配列内の値(文字列)を配列名とともに標準出力するプログラムを作成してください. 【プロトタイプ宣言】 void swapstr(char *str1, char *str2); 【実行結果】 2 つの文字列を入力してください apple strawberry 入れ換え前 配列str1 = apple 配列str2 = strawberry 入れ換え後 配列str1 = strawberry 配列str2 = apple

  • C言語の問題

    C言語を勉強している初心者です。大学の課題なのですが、よくわかりません。 5人分の名前と点数を入力し、点数の良い順に並べ替えよ。並べ替えの部分には関数(配列またはポインタ)を使用すること。 点数を入力させるのは分かるのですが、同時に名前の文字列を入力させるのがわかりません。 ソートも名前と点数を同時に並べ替えるやり方がわかりません。 宜しくお願いします。何分、初心者なので…申し訳ありません。宜しくお願いします。

  • C言語が学びやすいおススメの問題集を教えてください。

    C言語を問題を解きながら実践形式で覚えたいと思っています。 今の僕のレベルは、基本的な参考書を1冊読んだ程度で、 基本的な部分や簡単な配列などがどうにかできるくらい。ポインタや構造体などは一応読みましたが きちんと理解して使いこなせるかは疑問・・・といった程度です。 自分で探して目をつけた本としては、柴田望洋の「解きながら学ぶC言語」があります。 この本はどうでしょうか? その他におススメの本はないでしょうか? ぜひ教えてください。