Description
Give a dictionary with a total number of characters not exceeding 1,000,000 (the dictionary's word order is not dictionary) and no more than 1000 prefixes with a length of not more than 1000, the output dictionary matches the prefix, and the dictionary is the position of the k_i word in the dictionary.
All the words are lowercase letters.
Input Format
First line: Two integer n,m, representing the number of words in the dictionary and the number of prefixes that need to be queried.
Next n rows, one string per line representing the words in the dictionary.
Next m lines, one k_i per line, p_i, p_i represent the prefix of the query, and k_i represents the position of the prefix in the dictionary order.
Output Format
An M-line integer that represents the position of the qualified word in the dictionary. If no word satisfies the requirement, output-1
The example explained that the word conforming to the prefix ' a ' had {' AZ ', ' ay '}, sorted by dictionary order as {' ay ', ' az '}, and the 2nd dictionary order was AZ, in the first position of the dictionary.
Input Sample
3 2azayb2 a3 a
Output Sample
1-1
The simplest idea is to build on the structure of the trie tree and then query the DFS (each line in reverse order) to find the word prefixed by that prefix, find the K and return the original ID.
But such a query when a certain prefix of the word is more and k larger when the achievement and query time will be very long
So you can completely use the trie tree, directly with the dictionary order + binary search can be. (The idea of the standard process)
If you want to optimize on the trie, it is also possible, first in the dictionary order, and then trie find the first word, return to the dictionary sequence ID to determine whether the dictionary word id+k-1 the prefix.
My code is as follows:
#include <iostream>#include<cstring>#include<algorithm>#include<cstdio>using namespacestd;Const intMAXN = -;//the structure of the wordstructword{Charword[ -];//the content of the word intWord_len;//the length of the word intori_id;//The original ID of the word}; Word dictionary[1000000];//The storage dictionary is then sorted into a dictionary order//node of the treestructtrienode{BOOLIsend;//is the end character of a word intSoncount;//number of child nodestrienode* SON[MAXN];//The child node pointer list has a maximum of 26 intId//The position of the word ending with this node character in the sorted dictionaryTrienode () {isend=false; Soncount=0; ID= -1; for(inti =0; i < MAXN; ++i) son[i]=NULL; }}; Trienode* stack[1000000] = {0};//the stack for DFSTrienode* ROOT;//the root node represents the entire dictionary tree//Insert a word that gives the length of the word's content and the position of the word in the word listvoidInsertChar* Word,intLenintID) {Trienode* Curnode = root;//start with the root node//cout<<root->soncount<<endl; for(inti =0; i < Len; ++i) {//determine if word[i] is in Curnode's child node list intindex = word[i]-'a';//Index 0~25 if(Curnode->son[index]==null) {//without this characterCurnode->son[index] =NewTrienode (); //number plus onecurnode->soncount++; } if(i==len-1){//the end of a wordCurnode->son[index]->isend =true; Curnode->son[index]->id =ID; } Curnode= curnode->Son[index]; }}BOOLCmp_int (Const int& A,Const int&b) { returnA <b;}//Dictionary OrderingBOOLCmp_word (Constword& A,Constword&b) { intTodo = A.word_len < B.word_len?A.word_len:b.word_len; for(inti =0; i < Todo; ++i) {if(a.word[i]==B.word[i])Continue; returnA.word[i] <B.word[i]; } //at this point, there is no return statement that two words contain each other and put the little one in front. returnA.word_len <B.word_len;}//Query the first CNT word based on the prefix returns the ID in the dictionaryintFindintCntChar* prefix,intLen) {Trienode* Curnode =Root; for(inti =0; i < Len; ++i) {intCID = prefix[i]-'a'; if(Curnode->son[cid]! =NULL) {Curnode= curnode->Son[cid]; } } //The node with the last character of the prefix has now been found inttop =0; Stack[top++] =Curnode; //Dfs went to find the first word of the prefix while(Top >0) {Trienode* Tocheck = stack[--top]; if(tocheck->isend) { //return now returnTocheck->ID; }Else{ inthaveadded =0; for(inti = maxn-1; I >=0; --i) {if(Tocheck->son[i]! =NULL) {haveadded++; Stack[top+ +] = tocheck->Son[i]; if(haveadded==tocheck->soncount) Break; } } } } return-1;}//Determines whether word is prefixed with prefixBOOLIsIn (word& Word,Char* prefix,intLen) { if(Word.word_len <len)return false; for(intI=0; i < Len; i++){ if(Word.word[i]! =Prefix[i])return false; } return true;}intMainintargcChar Const*argv[]) { intn,m; CIN>>N>>M; Root=NewTrienode ();//initializing the root node for(inti =1; I <= N; ++i) {scanf ("%s", Dictionary[i].word); Dictionary[i].word_len=strlen (Dictionary[i].word); dictionary[i].ori_id=i; } Sort (Dictionary+1, dictionary+n+1, Cmp_word); for(inti =1; I <= N; ++i) Insert (Dictionary[i].word, Dictionary[i].word_len, i); Charpre[ ++Ten]; for(inti =0; i < M; ++i) {intK =0; scanf ("%d%s",&k,pre); //find the first word with the prefix prefixed by the sort ID + k-1 to determine if it is intFirst =Find (K,pre,strlen (pre)); if(first+k-1<=n and IsIn (dictionary[first+k-1],pre,strlen (PRE))) {cout<<dictionary[first+k-1].ori_id<<Endl; }Elsecout<<-1<<Endl; } return 0;}/*4 2adasaseasfg2 AS1 ad*/
trie+ Dictionary Ordering optimization
The standard range is as follows:
#include <iostream>#include<string>#include<vector>#include<algorithm>using namespacestd;intN, M;vector< pair<string,int> >dict;//determine if Word contains pref prefixes.BOOLMatchstring& Pref,string&word) { if(Pref.size () > Word.size ())return false; returnWORD.SUBSTR (0, pref.size ()) = =pref;} intMain () {CIN>> N >>m; for(inti =0; I < n; i++) { strings; CIN>>s; Dict.push_back (Make_pair (S, i));//pair's Word and ID } //Row Dictionary order because string has overloaded greater than number so do not join the functionsort (Dict.begin (), Dict.end ()); for(inti =0; I < m; i++) { intK; stringpref; CIN>> k >>pref; K--;//because the ID starts with 0//binary search for STL intpos = Lower_bound (Dict.begin (), Dict.end (), Make_pair (Pref,0)) -Dict.begin (); //Ignore whether Pos even matches at all intposs = pos +K; if(Poss < Dict.size () &&match (pref, Dict[poss].first)) {cout<< Dict[poss].second +1<<'\ n'; } Else{cout<<-1<<'\ n'; } }}
STL Standard Process
"Algorithmic learning note" 57. Prefix Tree Dictionary optimization techniques STL Learning SJTU OJ 1366 prefix matching