English | Japanese
最終更新日: 2002-10-22 (公開日: 2002-10-22)
file_name のファイルに対して、 UTF-8エンコーディングの文字単 位で Suffix Arrayを作成し、ファイル (file_name.ary) に格納す る。より詳しい例は mksary.c を参 照のこと。
#include <stdlib.h> #include <errno.h> #include <sary.h> int main (int argc, char **argv) { char *file_name; SaryInt ipoints; gboolean status; SaryBuilder *builder; if (argc != 2) exit(2); file_name = argv[1]; builder = sary_builder_new(file_name); sary_builder_set_ipoint_func(builder, sary_ipoint_char_utf8); ipoints = sary_builder_index(builder); if (ipoints == -1) { g_print("error: %s(.ary): %s\n", file_name, g_strerror(errno)); exit(2); } status = sary_builder_sort(builder); if (status == FALSE) { g_print("error: %s(.ary): %s\n", file_name, g_strerror(errno)); exit(2); } sary_builder_destroy(builder); return 0; }
file_name のファイルに対して、pattern で検索を行い、検索結果 を出現位置順にソートし、行単位で表示する。検索には file_name 用に構築された Suffix Array が必須。より詳しい例は sary.c を参照のこと。
#include <stdlib.h> #include <errno.h> #include <sary.h> int main (int argc, char **argv) { SarySearcher *searcher; char *pattern; char *file_name; if (argc != 3) exit(2); pattern = argv[1]; file_name = argv[2]; searcher = sary_searcher_new(file_name); if (searcher == NULL) { g_print("error: %s(.ary): %s\n", file_name, g_strerror(errno)); exit(2); } if (sary_searcher_search(searcher, pattern)) { gchar *line; sary_searcher_sort_occurrences(searcher); while ((line = sary_searcher_get_next_line(searcher))) { g_print("%s", line); g_free(line); } } sary_searcher_destroy(searcher); return 0; }
libsary を用いたプログラム program.c をコンパイルするには次 のように実行します。本格的な開発には autoconf, automake, libtool の利用をお勧めします。
% gcc program.c -o program `pkg-config sary --libs` `pkg-config sary --cflags`
SaryBuilder* sary_builder_new (const gchar *file_name)
SaryBuilder* sary_builder_new2 (const gchar *file_name, const gchar *array_name);
void sary_builder_destroy (SaryBuilder *builder);
void sary_builder_set_ipoint_func (SaryBuilder *builder, SaryIpointFunc ipoint_func);
SaryInt sary_builder_index (SaryBuilder *builder);
gboolean sary_builder_sort (SaryBuilder *builder);
gboolean sary_builder_block_sort (SaryBuilder *builder);
void sary_builder_set_block_size (SaryBuilder *builder, SaryInt block_size);
void sary_builder_set_nthreads (SaryBuilder *builder, SaryInt nthreads);
void sary_builder_connect_progress (SaryBuilder *builder, SaryProgressFunc progress_func, gpointer progress_func_data);
gchar* sary_ipoint_char_ascii (SaryText *text)
gchar* sary_ipoint_char_eucjp (SaryText *text)
gchar* sary_ipoint_char_sjis (SaryText *text)
gchar* sary_ipoint_char_utf8 (SaryText *text)
gchar* sary_ipoint_line (SaryText *text)
注意: sary_searcher_search2, sary_searcher_get_next_line2, sary_searcher_get_next_context_lines2, sary_searcher_get_next_tagged_region2 はスクリプト言語用のバンディ ングを書く人、あるいは効率に熱心な人のために用意されています。 これらの関数では文字列は長さとともに扱われるため、'\0' 文字 を中に含んでも構いません。新しい文字列が生成されることはあり ません。
SarySearcher* sary_searcher_new (const gchar *file_name)
SarySearcher* sary_searcher_new2 (const gchar *file_name, const gchar *array_name)
void sary_searcher_destroy (SarySearcher *searcher)
void sary_searcher_enable_cache (SarySearcher *searcher)
gboolean sary_searcher_search (SarySearcher *searcher, const gchar *pattern)
gboolean sary_searcher_search2 (SarySearcher *searcher, const gchar *pattern, SaryInt len)
gboolean sary_searcher_isearch (SarySearcher *searcher, const gchar *pattern, SaryInt len)
gboolean sary_searcher_isearch_reset (SarySearcher *searcher)
gboolean sary_searcher_icase_search (SarySearcher *searcher, const gchar *pattern)
gboolean sary_searcher_icase_search2 (SarySearcher *searcher, const gchar *pattern, SaryInt len)
SaryText* sary_searcher_get_text (SarySearcher *searcher)
SaryMmap* sary_searcher_get_array (SarySearcher *searcher)
gchar* sary_searcher_get_next_line (SarySearcher *searcher)
gchar* sary_searcher_get_next_line2 (SarySearcher *searcher, SaryInt *len)
gchar* sary_searcher_get_next_context_lines (SarySearcher *searcher, SaryInt backward, SaryInt forward)
gchar* sary_searcher_get_next_context_lines2 (SarySearcher *searcher, SaryInt backward, SaryInt forward, SaryInt *len)
gchar* sary_searcher_get_next_tagged_region (SarySearcher *searcher, const gchar *start_tag, const gchar *end_tag)
gchar* sary_searcher_get_next_tagged_region2 (SarySearcher *searcher, const gchar *start_tag, SaryInt start_tag_len, const gchar *end_tag, SaryInt end_tag_len, SaryInt *len)
SaryText* sary_searcher_get_next_occurrence (SarySearcher *searcher)
SaryInt sary_searcher_get_next_occurrence (SarySearcher *searcher)
SaryInt sary_searcher_count_occurrences (SarySearcher *searcher)
void sary_searcher_sort_occurrences (SarySearcher *searcher)
テキスト処理には SaryText オブジェクトを利用します。このオブ ジェクトはカーソルという状態を持っており、オブジェクトに対す る操作はこのカーソルを元にして行われます。
SaryText* sary_text_new (const gchar *file_name)
void sary_text_destroy (SaryText *text)
SaryInt sary_text_get_lineno (SaryText *text)
void sary_text_set_lineno (SaryText *text, SaryInt lineno)
SaryInt sary_text_get_linelen (SaryText *text)
gchar* sary_text_get_line (SaryText *text)
gchar* sary_text_get_region (SaryText *cursor, SaryInt len)
gboolean sary_text_is_eof (SaryText *text)
gchar* sary_text_get_cursor (SaryText *text)
void sary_text_set_cursor (SaryText *text, gchar *cursor)
gchar* sary_text_get_bof (SaryText *text)
gchar* sary_text_get_eof (SaryText *text)
gchar* sary_text_goto_bol (SaryText *text)
gchar* sary_text_goto_eol (SaryText *text)
gchar* sary_text_goto_next_line (SaryText *text)
gchar* sary_text_goto_next_word (SaryText *text)
gchar* sary_text_forward_cursor (SaryText *text, SaryInt len)
gchar* sary_text_backward_cursor (SaryText *text, SaryInt len)
mksary.c の progress_bar 関数を参考にしてください。
インデックスポイントの割り当ては Perl などのスクリプト言語で 簡単に行うことができます。複雑なテキスト処理を要するときはス クリプト言語を利用すると便利です。次の例は行頭にインデックス ポイントを割り当てる例です。
% cat line-indexer.pl $offset = 0; while (<>) { print pack 'N', $offset; $offset += length; } % perl line-indexer.pl foobar.txt > foobar.txt.ary
このようにして作成した foobar.txt.ary ファイルを mksary -s でソートすれば、 Suffix Array が完成します。
% mksary -s foobar.txt