• ベストアンサー

ハッシュ法でのデータ管理について教えてください

SHIMAPEEの回答

  • SHIMAPEE
  • ベストアンサー率75% (154/203)
回答No.7

ANo.5の改造版の抜粋です。チェーン内でキーが昇順になるようにしてみました。WindwosXP+Delphi2007で試しました。 ANo.5で、やや不自然か、とコメントしたのは、挿入した逆順に表示されるからです。そう作ったのだからそれはそうなのですが、挿入した順に表示された方が人間にはわかりやすいと思いました。 今回、更に考えてキーの昇順にしてみました。キーの大小関係を見ながら検索、挿入するので衝突が多い場合は性能向上が図れると思います。ま、いろいろ勉強してみました、ということでご参考まで。 function search(x:charstring; var p:list): boolean; var previous:list; comp:integer; begin Result:=false; previous:=nil; p:=hashtable[hash(x)]; while p<>nil do begin {ハッシュ表が空の場合、pはnilを返す。} comp:=strLcomp(p^.key, x, sizeof(x)-1); if comp=0 then begin {キーが一致したならば、} Result:=true; {結果をtrueにして、} break {pはキーが一致したレコードを返す。} end; if comp<0 then begin {xの方が大きければ、} if p^.next<>nil then begin {次のレコードがあれば、} previous:=p; {前のレコードの位置を覚えて、} p:=p^.next; {チェーンをたどる。} end else {次のレコードがなければ、} break {pはチェーン最後のレコードを返す。} end else begin {xの方が小さければ、} p:=previous; {pは前のレコードの位置を返す。先頭だった場合はnilを返す。} break end; end; end; procedure insert(x:charstring; y:integer; previous:list); var h : integer; newp : list; begin h := hash(x); new(newp); newp^.key := x; newp^.othertype := y; if previous=nil then begin {前のレコードがなければ、} newp^.next:=hashtable[h];{先頭に挿入する。} hashtable[h]:=newp end else begin {前のレコードがあれば} newp^.next:=previous.next;{そのレコードの次に挿入する。} previous.next:=newp; {(チェーン内のキーは昇順)} end; end;  :  : 'r':begin {登録=========================================================} write('キー :'); readln(strx); write('データ:'); readln(stry); for ix:=0 to sizeof(x)-1 do x[ix]:=#0; strLCopy(x, PChar(strx), sizeof(x)-1); y:=StrtoIntDef(stry, 0); if search(x, p) then writeln('キー"'+x+'"は既に登録されています。データ:', IntToStr(p^.othertype)) else insert(x, y, p); end;

kkk152
質問者

お礼

Resultはsearchのことだと思うのですが,strLcomp、strLCopy、StrtoIntDefとかって何のことですか??

関連するQ&A

  • ハッシュについて

    今、CGI作りに挑戦しているものです。 $data{a0} = "文字列"; とハッシュに「文字列」を入れて、 $sign = '0'; print "$data{a$sign}"; とやって、 「文字列」を表示させようとしたのですが、 Can't call method "a" without a package or object reference at test.cgi line *. と表示されて、「文字列」を表示できません。 ご教授いただけますようお願いします。

    • ベストアンサー
    • Perl
  • ハッシュ(オープンアドレス法) C言語の課題

    努力はしてみたのですが、C言語の課題ができません。教えていただけないでしょうか。 問:名前と年齢を入力し、名前をキーとしてハッシュ(オープンアドレス法)に登録する。'-'が入力されると登録を終了し、次に入力された名前をハッシュ法で検索し、あればその人のデータをハッシュから削除する、その後、ハッシュ表の内容を出力するプログラムを作成せよ。ただしハッシュ表の大きさは5とする。 例 koizumi  入力 1     入力 fukuda  入力 2  入力 aso 入力 3     入力 -     入力 koizumi  入力 fukuda(2) 出力 aso(3) 出力 ハッシュ関数は int hash(char *name) { int ret=0; while (*name)ret += *name++; return ret%5; } 再ハッシュ関数は int rehash(int h) { return (h+1)%5; } を使おうと考えています。 内容を理解できないと困るので簡単なプログラムをお願いします。 よろしくお願いします。

  • ハッシュについて

    今ハッシュについて勉強しています。 hashtableクラスを使用して3つのキーに1つずつ値をいれて、その後全部のキーと値を表示したり、値を更新したり、削除したいしたいと思っています。 全部のキーと値を表示させるにはどのように記述すればいいのでしょうか? おすすめのサイトなどあったらおしえてください!!

    • ベストアンサー
    • Java
  • フォームデータをハッシュで返すには?

    前画面の入力内容を&ReadParse()を用いて取得し、 その後テキストボックス名などのオブジェクト名と 入力内容をEUCに変換してハッシュで返すという サブルーチンを作っています。 サブルーチンなので不特定多数の画面から呼び出されます。 下記のとおりにしてみたのですが、うまくハッシュに入っていないらしく、値を取得することができません。 どのようにすればいいでしょうか? ----以下プログラム---- sub Comp_SetParam { &ReadParse(*form); # パラメータ受取 #引数として渡されたフォームデータを格納 while(($key,$val) = each(%form)){  #キー名(画面のオブジェクト名)をEUC変換  &jcode::convert(*key ,'euc');  #画面入力値をEUC変換  &jcode::convert(*val ,'euc');  %in = ("$key" => "$val"); } #ハッシュにし返す  return %in; }

    • ベストアンサー
    • Perl
  • 2次元ハッシュ または 2次元配列をソートしたい

    2次元ハッシュのソートをしたいです。 ハッシュは2つのキーを使用していて、 1つ目のキーは文字列、2つ目のキーは数字(0からの連番)です。 ハッシュの中身は文字列が入っています。 これを次のような表に見立てて、特定の列でソートしたいのです。 hash['a']['0'], hash['a']['1'], ..., hash['a']['50'], hash['q']['0'], hash['q']['1'], ..., hash['q']['50'], hash['c']['0'], hash['c']['1'], ..., hash['c']['50'], ... hash['d']['0'], hash['d']['1'], ..., hash['d']['50'], 例えば 6列目の値によってソートするということです。 以下のようにソートしようとしましたが、うまくいきません。 my @sorthash = sort { $a->[6] <=> $b->[6] } @hash; 何かヒントがあれば教えてください。

    • ベストアンサー
    • Perl
  • ハッシュ探索とはどういうイメージなのか?

    ハッシュ探索というのは「対象となるデータから一定の手順で算出したハッシュ値を用いてデータ本体の代わりに比較に用いる方式」ということですが、どういうものなのかイメージが思いつきません。 これはつまり、データ本体を「ハッシュ」という文字列に変換して、ハッシュ値として出力したものを、比較する(全ての文字列において比較する)というイメージでよいのでしょうか? もしそうだとしたら、ハッシュ値の長さ(文字列の長さ)に応じて(比較)処理時間が変わってくるのでしょうか? 例えば、(あくまで例です。) 6文字程度のハッシュ値→0.2秒で(比較処理時間が)終わる 3万文字程度のハッシュ値→3秒ぐらい(比較処理時間が)かかる ↑こういう風にハッシュ探索は文字列の長さに応じて処理時間が変化するのでしょうか? 回答のほうお願いします。

  • ハッシュの中身の表示

    ハッシュの中身の確認ができなくて困っています。 下記のような実行文においてです。 当然、test の戻り値は、スカラーとハッシュです。ハッシュを戻すときには参照渡し記号の\もつけています。 my ($return_code, %hash_data) = test(); 表示しようとすると、 Hash(0x5b04) のような表示にしかなりません、、 (試した表示方法は、下記4つです。) (環境は、WindowsXP上での、ActivePerl-5.10.0.1004 です。) foreach $key ( keys( %Hash ) ) { print "キー値 : $key\n"; print "値 : $Hash{$key} \n " } while ( ( $key , $value ) = each %Hash ){ print "キー値 : $key\n"; print "値 : $value \n " ; } use Data::Dump qw(dump); print dump(\%hash); #print %display_test; 宜しくお願いします。

    • ベストアンサー
    • Perl
  • パスワードのハッシュ化について

    ユーザー登録させるようなwebサイトを作ることになりました。 ググッたところパスワードはハッシュ化させDBへ、っていうのが通常らしいんで、 sha256を使って変換しようと思います。 質問(1)ハッシュ化させる元の文字列には文字数など何か制限はないんでしょうか。 質問(2)ハッシュ化させるときにくっつけるsaltは何桁くらいにするのが一般的なんでしょうか。 教えてください。

  • ハッシュテーブルの使い方

    こんにちわ。 いまVB.Net2003でプログラミングをしている者です。 ORACLEのあるテーブルの内容をハッシュテーブルに取り込んで, キー検索する処理をしたいのですが, 取り込む際,ハッシュテーブルの「Add」メソッドで 1件ずつ取り込むしかないのでしょうか? たとえばコンボボックスの「DataSource」プロパティに レコードセットを設定するように,一回で設定したいのですが, このような機能があるでしょうか? またハッシュテーブルはキーは1つしか設定できないようですが, このテーブルデータを2つのキーで検索するのはどうすれば 良いでしょうか?

  • ハッシュ

    この問題の解き方を出来ればわかりやすくお願いします。 疑問:データと書いてある所に16進数の解答の答えを10進数に直していれるのでしょうか? 問題↓ 表A ーーーーーーーーーーーーーーーーー データと格納順 7B→B5→A7→58→FE→6A→7D→E9→88 ーーーーーーーーーーーーーーーーー ハッシュ値を f(データ)=mod(データ,8) で求めたとき最初に衝突が起こる。(上の表Aにあるデータと等しいハッシュ値になる)のはどのデータか。mod(a,b)はaをbで割った余りを表す。 a 6A b E9 c 7D d 88 (問題の解答はもとめておりません)