// Inserts a word into the trie. void insert(string word) { TrieNode *cur = root, *tmp; for (auto c: word) { if ((tmp = cur->find(c)) == NULL) { tmp = cur->insert(c); } cur = tmp; } cur->insert('\0'); }
void acTest() { TrieNode* trie = new TrieNode(); trie->insert("SHE", 0); trie->insert("HE", 1); trie->insert("HERS", 2); trie->insert("HIS", 3); computeFailFunc(trie); map<TrieNode*, string> nodeToStr; queue<pair<TrieNode*,string> > q; q.push(make_pair(trie, "")); while(!q.empty()) { TrieNode* here = q.front().first; string label = q.front().second; q.pop(); nodeToStr[here] = label; printf("[%s] => [%s]\n", label.c_str(), nodeToStr[here->fail].c_str()); for(int i = 0; i < ALPHABETS; i++) { if(here->children[i]) q.push(make_pair(here->children[i], label + char('A' + i))); } } assert(nodeToStr[find(trie, "SH")->fail] == "H"); assert(nodeToStr[find(trie, "SHE")->fail] == "HE"); assert(nodeToStr[find(trie, "HIS")->fail] == "S"); assert(nodeToStr[find(trie, "HERS")->fail] == "S"); // 012345678 accumulated = ahoCorasick(string("HERSHISHE"), trie); // HE at 1 // HERS at 3 // HIS at 6 // SHE at 8 // HE at 8 sort(accumulated.begin(), accumulated.end()); for(int i = 0; i < (accumulated.size()); i++) { printf("accumulated[%d] = (%d,%d)\n", i, accumulated[i].first, accumulated[i].second); } assert(accumulated.size() == 5); assert(accumulated[0] == make_pair(1, 1)); assert(accumulated[1] == make_pair(3, 2)); assert(accumulated[2] == make_pair(6, 3)); assert(accumulated[3] == make_pair(8, 0)); assert(accumulated[4] == make_pair(8, 1)); }
void insert(char c) { TrieNode *pCN = root; if (root == nullptr) { root = new TrieNode(); } else { root->insert(c); } }
void naiveTest() { TrieNode* trie = new TrieNode(); trie->insert("HELLO",1); assert(1 == trie->find("HELLO")->terminal); assert(NULL == trie->find("HELLOB")); assert(-1 == trie->find("HELL")->terminal); delete trie; }
int main() { TrieNode* ptn = new TrieNode(); std::string s = "BANANAS"; for (int i = 0; i < s.size(); ++i) { // printf("%s\n", s.substr(i).c_str()); ptn->insert(s.substr(i).c_str()); } TrieNode* ptn0 = ptn->find("NAS"); if (ptn0) printf("%s is in", "NAS"); delete ptn; }
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) { vector<string> res; if (board.empty() || board[0].empty() || words.empty()) return res; int m = board.size(), n = board[0].size(); vector<vector<bool>> visited(m, vector<bool>(n, false)); TrieNode* trie = new TrieNode(); for (int i = 0; i < words.size(); i++) trie->insert(words[i]); unordered_set<string> set; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) DFS(board, "", trie, visited, set, i, j); } for (auto& elem : set) res.push_back(elem); sort(res.begin(), res.end()); return res; }
int solve(int length, const vector<string>& patterns) { // 트라이를 만든다 TrieNode trie; for(int i = 0; i < patterns.size(); i++) trie.insert(patterns[i].c_str(), i); // 실패 함수를 계산 computeFailFunc(&trie); // 상태 전이 테이블을 생성한다 int t = 0; computeTransition(&trie, t); // 동적 계획법을 위한 캐시를 초기화 memset(cache, -1, sizeof(cache)); return count(length, &trie); }
int main(){ char words[WORD_NUM_MAX+1][WORD_LEN_MAX+1]; int wordNum=0; TrieNode root; while(true){ if(scanf("%s",words[wordNum])==EOF) break; root.insert(words[wordNum]); wordNum++; } for(int i=0;i<wordNum;i++){ printf("%s",words[i]); int len=root.prefixLen(words[i]); words[i][len]='\0'; printf(" %s\n",words[i]); } return 0; }
int main() { scanf("%s%s", S+1, T+1); SL = strlen(S+1); TL = strlen(T+1); TrieNode* trie = new TrieNode(0, 0); for (int i = 1; i <= SL; i++) { TrieNode* node = trie; for (int j = i; j <= SL; j++) { node = node->insert(S[j], i, j); } TrieNode* node2 = trie; for (int j = i; j > 0; j--) { node2 = node2->insert(S[j], i, j); } } for (int i = TL; i > 0; i--) { dp[i] = INF; TrieNode* node = trie; for (int j = i; j <= TL; j++) { if (node) { node = node->next(T[j]); int v = dp[j+1]+(node ? 1 : INF); if (v < dp[i]) { dp[i] = v; ans[i] = node; tr[i] = j+1; } } } } if (dp[1] >= INF) { printf("-1\n"); } else { printf("%d\n", dp[1]); int i = 1; for (int j = 0; j < dp[1]; j++) { printf("%d %d\n", ans[i]->a, ans[i]->b); i = tr[i]; } } return 0; }
// 입력에 주어지는 단어들을 정렬해서 트라이로 변환한다 TrieNode* readInput(int words) { // 단어들을 출현 빈도의 내림차순, 단어의 오름차순으로 정렬한다 vector<pair<int,string> > input; for(int i = 0; i < words; i++) { char buf[11]; int freq; scanf("%s %d", buf, &freq); input.push_back(make_pair(-freq, buf)); } sort(input.begin(), input.end()); // 이 때 앞에 있는 단어일 수록 우선 순위가 높다. // 배열의 인덱스를 각 단어의 번호로 쓰자. TrieNode* trie = new TrieNode(); for(int i = 0; i < input.size(); i++) trie->insert(input[i].second.c_str(), i); // 아무 문자도 입력하지 않은 상황에서는 자동 완성되지 않아야 한다 trie->first = -1; return trie; }
void typeahead(const vector<string> &usernames, const vector<string> &queries){ TrieNode* trie = new TrieNode(); for (vector<string>::const_iterator it = usernames.begin(), stop = usernames.end(); it != stop; ++it) { char word[it->size() + 1]; strcpy(word, it->c_str()); trie->insert(word, it->c_str()); } for (vector<string>::const_iterator it = queries.begin(), stop = queries.end(); it != stop; ++it) { char word[it->size() + 1]; strcpy(word, it->c_str()); string result; trie->query(word, result); if (result.empty()) { cout << -1 << '\n'; } else { cout << result << '\n'; } } }
// Output our entire accumulated state as XML. void LocalState::output_xml (ostream& of) { // Output the header boilerplate. We use SecCallPathProfile instead of // SecFlatProfile because I've not seen an example of the latter and even had // trouble producing a SecFlatProfile that was acceptable to HPCViewer. id = 0; of << hpcviewer_header_boilerplate << "<HPCToolkitExperiment version=\"2.0\">\n" << " <Header n=\"" << short_infilename << "\">\n" << " <Info/>\n" << " </Header>\n" << " <SecCallPathProfile i=\"" << id++ << "\" n=\"" << short_infilename << "\">\n" << " <SecHeader>\n"; // Define each of our metrics (table columns). vector<Column*>& table = table_data; of << " <MetricTable>\n"; for (auto citer = table.begin(); citer != table.end(); citer++) { // Include only integer columns (except line numbers). Column* column = *citer; if (column->type != Column::UINT64_T) continue; string cname(column->name); if (cname == "Line number" || cname == "Leaf line number") continue; // Output the column name as a metric. of << " <Metric i=\"" << id++ << "\" n=\"" << cname << "\" v=\"raw\" t=\"exclusive\" show=\"1\" show-percent=\"0\" />\n"; } of << " </MetricTable>\n"; // Output an empty metric-database table. of << " <MetricDBTable>\n" << " </MetricDBTable>\n"; // Output a load-module table. string load_module(infilename); // Fabricate a load module name based on the input filename. size_t last_dot_pos = load_module.rfind('.'); if (last_dot_pos != string::npos) load_module = load_module.substr(0, last_dot_pos); loadmod_id = id++; of << " <LoadModuleTable>\n" << " <LoadModule i=\"" << loadmod_id << "\" n=\"" << load_module << "\"/>\n" << " </LoadModuleTable>\n"; // Find the line-number column. lineno_col = nullptr; for (auto citer = table.begin(); citer != table.end(); citer++) { Column* column = *citer; string colname(column->name); if (colname == "Line number" || colname == "Leaf line number") lineno_col = column; } if (lineno_col == nullptr) cerr << progname << ": Failed to find a \"Line number\" or \"Leaf line number\" column in the \"Functions\" table\n" << die; if (lineno_col->type != Column::UINT64_T) cerr << progname << ": The \"" << lineno_col->name << "\" column does not contain integer data\n" << die; // Construct a mapping from file name to ID. file_col = nullptr; for (size_t i = 0; i < table.size(); i++) if (table[i]->name == "File name" || table[i]->name == "Leaf file name") { file_col = table[i]; break; } if (file_col == nullptr) cerr << progname << ": Failed to find a \"File name\" or \"Leaf file name\" column in the \"Functions\" table\n" << die; if (file_col->type != Column::STRING_T) cerr << progname << ": The \"" << file_col->name << "\" column does not contain string data\n" << die; of << " <FileTable>\n"; for (auto riter = file_col->string_data->begin(); riter != file_col->string_data->end(); riter++) { string fname = *riter; if (fname2id.find(fname) != fname2id.end()) continue; fname2id[fname] = id; if (fname == "") of << " <File i=\"" << id << "\" n=\"~unknown-file~\"/>\n"; else of << " <File i=\"" << id << "\" n=\"./src" << quote_for_xml(fname) << "\"/>\n"; id++; } of << " </FileTable>\n"; // Construct a mapping from demangled function name or demangled call stack // to ID. size_t func_col_num; func_col = nullptr; for (size_t i = 0; i < table.size(); i++) if (table[i]->name == "Demangled function name" || table[i]->name == "Demangled call stack") { func_col_num = i; func_col = table[i]; break; } if (func_col == nullptr) cerr << progname << ": Failed to find a \"Demangled function name\" or \"Demangled call stack\" column in the \"Functions\" table\n" << die; if (func_col->type != Column::STRING_T) cerr << progname << ": The \"" << func_col->name << "\" column does not contain string data\n" << die; of << " <ProcedureTable>\n"; for (auto riter = func_col->string_data->begin(); riter != func_col->string_data->end(); riter++) { string func = *riter; if (func2id.find(func) != func2id.end()) continue; func2id[func] = id; of << " <Procedure i=\"" << id << "\" n=\"" << quote_for_xml(func.substr(0, func.find(" # "))) << "\"/>\n"; id++; } of << " </ProcedureTable>\n" << " </SecHeader>\n"; // Insert each call path into a trie forest then output the trie (except the // root, which exists solely to store the forest). size_t nrows = func_col->string_data->size(); call_forest = new LocalState::TrieNode(this); for (size_t r = 0; r < nrows; r++) call_forest->insert(func_col_num, r); of << " <SecCallPathProfileData>\n"; for (auto titer = call_forest->children.begin(); titer != call_forest->children.end(); titer++) titer->second->output_xml(of, 0); of << " </SecCallPathProfileData>\n"; // Output the trailer boilerplate. of << " </SecCallPathProfile>\n" "</HPCToolkitExperiment>\n"; }
// Construct various tables in preparation for output. void LocalState::finalize (void) { // Find the line-number column. lineno_col = nullptr; for (auto citer = table_data.begin(); citer != table_data.end(); citer++) { Column* column = *citer; string colname(column->name); if (colname == "Line number" || colname == "Leaf line number") lineno_col = column; } if (lineno_col == nullptr) cerr << progname << ": Failed to find a \"Line number\" or \"Leaf line number\" column in the \"Functions\" table_data\n" << die; if (lineno_col->type != Column::UINT64_T) cerr << progname << ": The \"" << lineno_col->name << "\" column does not contain integer data\n" << die; // Find the invocation-count column. invoke_col = nullptr; for (auto citer = table_data.begin(); citer != table_data.end(); citer++) { Column* column = *citer; string colname(column->name); if (colname == "Invocations") invoke_col = column; } if (invoke_col == nullptr) cerr << progname << ": Failed to find an \"Invocations\" column in the \"Functions\" table_data\n" << die; if (invoke_col->type != Column::UINT64_T) cerr << progname << ": The \"" << invoke_col->name << "\" column does not contain integer data\n" << die; // Construct a mapping from file name to ID and back. size_t id = 1; file_col = nullptr; for (size_t i = 0; i < table_data.size(); i++) if (table_data[i]->name == "File name" || table_data[i]->name == "Leaf file name") { file_col = table_data[i]; break; } if (file_col == nullptr) cerr << progname << ": Failed to find a \"File name\" or \"Leaf file name\" column in the \"Functions\" table_data\n" << die; if (file_col->type != Column::STRING_T) cerr << progname << ": The \"" << file_col->name << "\" column does not contain string data\n" << die; for (auto riter = file_col->string_data->begin(); riter != file_col->string_data->end(); riter++) { string fname = *riter; if (fname2id.find(fname) != fname2id.end()) continue; fname2id[fname] = id; id2fname[id] = fname; id++; } // Construct a mapping from demangled function name or demangled call stack // to ID and back. id = 1; func_col = nullptr; for (size_t i = 0; i < table_data.size(); i++) if (table_data[i]->name == "Demangled function name" || table_data[i]->name == "Demangled call stack") { func_col = table_data[i]; break; } if (func_col == nullptr) cerr << progname << ": Failed to find a \"Demangled function name\" or \"Demangled call stack\" column in the \"Functions\" table\n" << die; if (func_col->type != Column::STRING_T) cerr << progname << ": The \"" << func_col->name << "\" column does not contain string data\n" << die; size_t row = 0; for (auto riter = func_col->string_data->begin(); riter != func_col->string_data->end(); riter++, row++) { string func = *riter; string func_only(func.substr(0, func.find(" # "))); if (func2id.find(func_only) != func2id.end()) continue; func2id[func_only] = id; id2func[id] = func_only; funcid2fnameid[id] = fname2id[(*file_col->string_data)[row]]; id++; } // Insert each call path into a trie forest. Compute inclusive and exclude // metrics. size_t func_col_num = func_col->number; size_t nrows = func_col->string_data->size(); call_forest = new LocalState::TrieNode(this); for (size_t r = 0; r < nrows; r++) call_forest->insert(func_col_num, r); auto citer = call_forest->children.begin(); if (citer != call_forest->children.end()) { // Initialize the root to have all-zero data. TrieNode* child = citer->second; call_forest->self_data.resize(child->self_data.size(), 0); call_forest->path_data.resize(child->path_data.size(), 0); } call_forest->propagate_data_upwards(); }
void insert(string &str) { root.insert(str,0); }