2012-06-14 :-(
_ [アルゴリズム辞典][パトリシア]アルゴリズム辞典 - パトリシア(C実装)
/* ------------------------------------------------------------------------- * アルゴリズム辞典 * 島内剛一 野下浩平 伏見正則 有沢誠 浜田穂積 * * パトリシア pp. 624-625 * ---------------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> typedef struct node { char key; char chckbit; struct node* right; struct node* left; } node; static node head = { 0x0, 0x0, &head, &head }; static char mask[9] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; // 探索 node* search ( char key, node* x ) { node* p; do { p = x; x = ( key & mask[ x->chckbit ] ) ? x->right : x->left; } while ( p->chckbit < x->chckbit ); return x; } // 挿入 void insert( char key, node* x ) { node* t, *p; int i; // キーの探索 t = search( key, x ); if( key == t->key ) { printf( "%c exists\n", key ); return; } // 挿入するキーと衝突するキーとの間で最初に // 異なるビットの位置を求める for( i = 1; ( key & mask[ i ] ) == ( t->key & mask[ i ] ); i++ ) ; // キーを置く位置( x )を求める do { p = x; x = ( key & mask[ x->chckbit ] ) ? x->right : x->left; } while( ( x->chckbit < i ) && ( p->chckbit < x->chckbit ) ); // 挿入する節点を生成し // キーと検査ビットの位置を設定する t = calloc( 1, sizeof( node ) ); t->key = key; t->chckbit = i; // 子節と親節を設定する if( key & mask[ t->chckbit ] ) { t->right = t; t->left =x; } else { t->left = t; t->right = x; } if( key & mask[ p->chckbit ] ) p->right = t; else p->left = t; return; } int main( int ac, char** av ) { node *np; insert( 'a', &head ); insert( 'b', &head ); insert( 'c', &head ); np = search( 'a', &head ); if( np != NULL ) printf( "key: %c\n", np->key ); np = search( 'b', &head ); if( np != NULL ) printf( "key: %c\n", np->key ); np = search( 'c', &head ); if( np != NULL ) printf( "key: %c\n", np->key ); return; }
% ./a.exe key: a key: b key: c
4320027094
_ [アルゴリズム辞典][パトリシア]アルゴリズム辞典 - パトリシア(ruby実装)
#!/usr/bin/ruby # -*- encoding: utf-8 -*- # # アルゴリズム辞典 # 島内剛一 野下浩平 伏見正則 有沢誠 浜田穂積 # # パトリシア pp. 624-625 require 'pp' class Node attr_accessor :key, :chckbit, :left, :right def initialize(key = 0, chckbit = 0, left = nil, right = nil) @key = key @chckbit = chckbit @left = left @right = right end end class Patricia def initialize() @head = Node.new() @head.key = 0 @head.chckbit = 0 @head.left = @head @head.right = @head @mask = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80] end # 探索 def search(key) x = @head p = nil begin p = x x = (key[0] & @mask[x.chckbit] != 0) ? x.right : x.left end while (p.chckbit < x.chckbit) return x end # 挿入 def insert(key) x = @head t = nil p = nil i = 0 # キーの探索 t = self.search(key) if key == t.key puts "#{key} exists" return end # 挿入するキーと衝突するキーとの間で最初に # 異なるビットの位置を求める i = 1 while (key[0] & @mask[i]) == (t.key[0] & @mask[i]) i += 1 end # キーを置く位置( x )を求める begin p = x x = (key[0] & @mask[x.chckbit] != 0) ? x.right : x.left end while ((x.chckbit < i) && (p.chckbit < x.chckbit)) # 挿入する節点を生成し # キーと検査ビットの位置を設定する t = Node.new() t.key = key t.chckbit = i # 子節と親節を設定する if key[0] & @mask[t.chckbit] != 0 t.right = t t.left =x else t.left = t t.right = x end if key[0] & @mask[p.chckbit] != 0 p.right = t else p.left = t end end end # end of Patricia def main(argv) pat = Patricia.new() pat.insert('a') pat.insert('b') pat.insert('c') np = pat.search('a') if np != nil puts "key: #{np.key}" end np = pat.search('b') if np != nil puts "key: #{np.key}" end np = pat.search('c') if np != nil puts "key: #{np.key}" end end main(ARGV)
% ruby patricia.rb key: a key: b key: c
4320027094
[ツッコミを入れる]