- Author: harajune
- Filed under: 雑記
Monday
Aug 31,2009
Txでdartsのようなtraverseをする関数を作ってみました。
使い方はdartsのtraverseと同じだと思います。たまたま作ったのでパッチをそのまま貼っておきます。動作は未保証。dartsよりも爆速でふきました。
CODE:
-
diff -cb tx-0.13/tx.cpp tx_original/tx.cpp
-
*** tx-0.13/tx.cpp 2009-04-13 13:21:14.000000000 +0900
-
--- tx_original/tx.cpp 2009-08-27 22:45:25.000000000 +0900
-
***************
-
*** 195,200 ****
-
--- 195,221 ----
-
return 0;
-
}
-
-
+ uint tx::traverse(const char* str, size_t& pos) const {
-
+ uint curPos = 2;
-
+ uint retId = NOTFOUND;
-
+ size_t begin = pos;
-
+ if (terminal.getSize() <= 2) return retId;
-
+
-
+ for (size_t i = 0 ; ; i++){
-
+ const uint nodeId = loud.rank(curPos-1,1)-1;
-
+ if (terminal.getBit(nodeId)){
-
+ pos = begin + i;
-
+ retId = terminal.rank(nodeId,1)-1;
-
+ }
-
+ uint nextPos = getChild(curPos,str[begin + i]);
-
+ if (nextPos == UINT_MAX){
-
+ break;
-
+ }
-
+ curPos = nextPos;
-
+ }
-
+ return retId;
-
+ }
-
+
-
uint tx::prefixSearch(const char* str, const size_t len, size_t& retLen) const {
-
uint curPos = 2;
-
uint retId = NOTFOUND;
-
diff -cb tx-0.13/tx.hpp tx_original/tx.hpp
-
*** tx-0.13/tx.hpp 2008-06-03 21:05:00.000000000 +0900
-
--- tx_original/tx.hpp 2009-08-27 22:41:04.000000000 +0900
-
***************
-
*** 26,31 ****
-
--- 26,32 ----
-
int read(const char* fileName);
-
-
uint prefixSearch(const char* str, const size_t len, size_t& retLen) const;
-
+ uint traverse(const char* str, size_t& pos) const;
-
uint expandSearch(const char* str, const size_t len, std::vector<std::string>& ret, const uint limit = 0) const;
-
uint commonPrefixSearch(const char* str, const size_t len, std::vector<std::string>& ret, std::vector<uint>& retID, const uint limit = TX_LIMIT_DEFAULT) const;
-
uint commonPrefixSearch(const char* str, const size_t len, std::vector<uint>& retLen, std::vector<uint>& retID, const uint limit = TX_LIMIT_DEFAULT) const;
-
***************
-
*** 42,48 ****
-
-
static uint NOTFOUND;
-
-
! private:
-
uint getChild(const uint pos, const char c) const;
-
uint getParent(const uint pos, char& c) const;
-
void enumerateAll(const uint pos, const std::string str, std::vector<std::pair<size_t, std::pair<std::string, uint>>>& ret) const;
-
--- 43,49 ----
-
-
static uint NOTFOUND;
-
-
! // private:
-
uint getChild(const uint pos, const char c) const;
-
uint getParent(const uint pos, char& c) const;
-
void enumerateAll(const uint pos, const std::string str, std::vector<std::pair<size_t, std::pair<std::string, uint>>>& ret) const;
- Author: harajune
- Filed under: IT
Friday
Aug 28,2009
はてなのようなキーワードリンクをRubyで付与する実例
と、いうのをつくってもらったので、これをもとにCでsennaのpatricia treeを試すプログラムを書いたよ。
機能的にはとりあえずキーワードの検出だけ。
CODE:
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <senna/senna.h>
-
#include <string.h>
-
//#include <exectime.h>
-
-
void create_index(char* index, char* filename){
-
-
sen_sym *sym;
-
-
if(!(sym = sen_sym_create(index, 0, SEN_INDEX_NORMALIZE, sen_enc_utf8))){
-
printf("cannot open or create sym file\m");
-
abort();
-
}
-
-
FILE * fp = fopen(filename, "rb");
-
-
char buffer[2048];
-
-
sen_id sym_id;
-
while(fgets(buffer, 2048, fp)){
-
sscanf(buffer, "%s\n", buffer);
-
if(!(sym_id = sen_sym_get(sym, buffer))){
-
printf("cannot create link\n");
-
abort();
-
}
-
-
// printf("%d\t", sym_id);
-
}
-
-
fclose(fp);
-
-
sen_sym_close(sym);
-
-
}
-
-
void traverse(char* index, char* filename){
-
printf("traverse\n");
-
sen_sym* sym;
-
-
if(!(sym = sen_sym_open(index))){
-
printf("cannot open index file\n");
-
abort();
-
}
-
-
FILE * fp = fopen(filename, "rb");
-
-
if(!fp){
-
printf("cannot open file\n");
-
abort();
-
}
-
-
fseek(fp, 0, SEEK_END);
-
-
int filesize = ftell(fp);
-
int offset = 0;
-
-
fseek(fp, 0, SEEK_SET);
-
-
char * content = new char[filesize + 1];
-
const char * cp = content;
-
-
-
fread(content, sizeof(char), filesize, fp);
-
content[filesize] = '\0';
-
-
sen_sym_scan_hit sh[32];
-
-
char buffer[2048];
-
-
const char * rest;
-
-
exectime::start_timer();
-
-
while((rest - content) <filesize){
-
int found;
-
if(!(found = sen_sym_scan(sym, cp, filesize, sh, 32, &rest))){
-
break;
-
}
-
-
for(int i=0; i<found; i++){
-
int key_len = sen_sym_key(sym, sh[i].id, buffer, 2048);
-
if(key_len> 0 && sh[i].length> 7){
-
printf("%s\n", buffer);
-
}
-
-
}
-
cp = rest;
-
-
}
-
-
exectime::end_timer();
-
-
printf("time: %f sec\n", exectime::time_result());
-
-
-
}
-
-
int main(int argc, char** argv){
-
-
if(!strcmp(argv[1], "make")){
-
create_index(argv[2], argv[3]);
-
}else if(!strcmp(argv[1], "traverse")){
-
traverse(argv[2], argv[3]);
-
}
-
-
}
Comments Off
- Author: harajune
- Filed under: 雑記
Tuesday
Aug 25,2009
Darts: Double-ARray Trie System
http://chasen.org/~taku/software/darts/
dartsというのは、Trie木をdouble arrayで実装したライブラリです。ヘッダファイル一つだけの配布なので大変使いやすい。
今回HAT-trieを実装してみるにあたって、Trie木の部分の実装としてこれを使ってみることにしました。
しかし、サンプルが動かない・・・・!どうやらよく見るとテンプレート周りとconstを付け加えた際に、もともとのサンプルが動かなくなった模様。
なので、これを修正しました。別に大したことはしていません。
CODE:
-
#include <iostream>
-
#include <darts.h>
-
-
int main (int argc, char **argv)
-
{
-
using namespace std;
-
-
const Darts::DoubleArray::key_type *str[] = { "ALGOL", "ANSI", "ARCO", "ARPA", "ARPANET", "ASCII" }; // same as char*
-
Darts::DoubleArray::result_type val[] = { 1, 2, 3, 4, 5, 6 }; // same as int
-
-
Darts::DoubleArray da;
-
da.build (6, str, 0, val);
-
-
cout <<da.exactMatchSearch<int>("ALGOL") <<endl;
-
cout <<da.exactMatchSearch<int>("ANSI") <<endl;
-
cout <<da.exactMatchSearch<int>("ARCO") <<endl;
-
cout <<da.exactMatchSearch<int>("ARPA") <<endl;
-
cout <<da.exactMatchSearch<int>("ARPANET") <<endl;
-
cout <<da.exactMatchSearch<int>("ASCII") <<endl;
-
cout <<da.exactMatchSearch<int>("APPARE") <<endl;
-
-
da.save("some_file");
-
}
Comments Off