Beispiel #1
0
    void init(const unordered_set<string> & wordlist, const string& beginWord,
              const string& endWord) {
        //init endWords
        for (unordered_set<string>::const_iterator iter = wordlist.begin();
                iter != wordlist.end(); ++iter) {
            if (isOneStep(endWord, *iter))
                this->endWords.insert(*iter);
        }

        //init beginWords
        for (unordered_set<string>::const_iterator iter = wordlist.begin();
                iter != wordlist.end(); ++iter) {
            if (isOneStep(beginWord, *iter))
                this->beginWords.insert(*iter);
        }

        //init oneStep
        for (unordered_set<string>::const_iterator i = wordlist.begin();
                i != wordlist.end(); ++i) {
            vector<string> tmp;
            for (unordered_set<string>::const_iterator j = wordlist.begin();
                    j != wordlist.end(); ++j)
                if (isOneStep(*i, *j)) {
                    tmp.push_back(*j);
                }
            this->oneStep[*i] = tmp;
        }
    }
Beispiel #2
0
    bool wordBreak(string s, unordered_set<string> &dict) {
        for(int i = 0; i < s.size(); i++){
            bool found = false;
            for(auto it = dict.begin(); it != dict.end(); it++){
                if(it->find(s.substr(i, 1)) != string::npos){
                    found = true;
                    break;
                }
            }
            if(found == false){
                return false;
            }
        }

        for(auto it = dict.begin(); it != dict.end(); it++){
            if(s.find(*it) == 0){
                if(it->size() == s.size()){
                    return true;
                }
                if(wordBreak(s.substr(it->size(), string::npos), dict)){
                    return true;
                };
            }
        }

        return false;
    }
 void topSort(unordered_set<char> &letters, vector<pair<char, char>> &partialOrders, string &order) {
     if (partialOrders.empty()) {
         for (auto it = letters.begin(); it != letters.end(); it++) {
             order.push_back(*it);
         }
         return;
     }
     // build adjacency list
     unordered_map<char, unordered_set<char>> adj;
     for (int i = 0; i < partialOrders.size(); i++) {
         pair<char, char> e = partialOrders[i];
         adj[e.first].insert(e.second);
     }
     unordered_set<char> visited;
     unordered_set<char> inStack;
     stack<char> s;
     for (auto it = letters.begin(); it != letters.end(); it++) {
         if (visited.find(*it) == visited.end()) {
             if (dfs(adj, *it, visited, inStack, s)) { // cycle found
                 return;
             }
         }
     }
     // no cycle found
     while (!s.empty()) {
         order.push_back(s.top());
         s.pop();
     }
     return; 
 } 
    // looking for connection from both ends
    bool bfs(unordered_set<string> &forward, unordered_set<string> &backward, bool isForward, 
                unordered_set<string> &wordList, unordered_map<string, vector<string>> &transMap) {
        if (forward.empty() || backward.empty())
        {
            return false;
        }

        // always do bfs with less nodes
        if (forward.size() > backward.size())
        {
            return bfs(backward, forward, !isForward, wordList, transMap);
        }

        // remove added node in the wordList to avoid duplication
        unordered_set<string>::iterator it;
        for (it = forward.begin(); it != forward.end(); it++)
        {
            wordList.erase(*it);
        }

        for (it = backward.begin(); it != backward.end(); it++)
        {
            wordList.erase(*it);
        }

        unordered_set<string> nextlevel;
        bool isConnected = false;
        for (it = forward.begin(); it != forward.end(); it++)
        {
            string word = *it;
            for (int i = 0; i < word.size(); i++)
            {
                for (char ch = 'a'; ch <= 'z'; ch++)
                {
                    if (word[i] != ch)
                    {
                        // word is in forward list, str is in backward list
                        string str(word);
                        str[i] = ch;
                        if (backward.find(str) != backward.end())
                        {
                            isConnected = true;
                            connect(word, str, isForward, transMap);
                        }
                        else if (!isConnected && wordList.find(str) != wordList.end())
                        {
                            nextlevel.insert(str);
                            connect(word, str, isForward, transMap);
                        }
                    }
                }
            }
        }

        return isConnected || bfs(nextlevel, backward, isForward, wordList, transMap);
    }
Beispiel #5
0
string tripleSetToString(const unordered_set<Triple>& st)
{
 string rval;
 for (auto it=st.begin(); it!=st.end(); it++)
 {
    if(it!=st.begin())
        rval += kInternalSetDelim;
    rval += tripleToString(*it);
}
return rval;
}
uint64_t unionSet(unordered_set<minimizer>& set1,unordered_set<minimizer>& set2){
	uint64_t res(0);
	for (auto it=set2.begin(); it!=set2.end(); ++it){
			++res;
	}
	for (auto it=set1.begin(); it!=set1.end(); ++it){
		if(set2.count(*it)==0){
			++res;
		}
	}
	return res;
}
Beispiel #7
0
		vector<string> wordBreakII(string s, unordered_set<string> &dict) {
			vector<string> res;
			vector<vector<unordered_set<string>::iterator> > record;
			
			/*
			printf("%s\n", s.c_str());
			for (unordered_set<string>::iterator usit = dict.begin(); usit != dict.end(); ++usit)
			{
				printf("%s\n", usit->c_str());
			}
			*/

			int len = (int)s.size();
			int *st = new int[len+1];
			memset(st, 0, sizeof(int) * (len+1));
			st[0] = 1;
			for (int i = 0; i <= len; ++i) record.push_back(vector<unordered_set<string>::iterator>());
			unordered_set<string>::iterator usit = dict.begin();

			for (int i = 1; i <= len; ++i)
			{
				for (usit = dict.begin(); usit != dict.end(); ++usit)
				{
					int cur_len = (int)usit->size();
					int dis = i - cur_len;
					if (dis < 0) continue; //too short, impossible
					const char *start = s.c_str() + dis;

					if (st[dis] == 1 && strncmp(start, usit->c_str(), cur_len) == 0)
					{
						st[i] = 1;
						record[i].push_back(usit);
					}
				}
			}

			//debug
			/*
			for (size_t i = 1; i < record.size(); ++i)
			{
				printf("%lu ==> ", i);
				for (size_t j = 0; j < record[i].size(); j++) printf("%s ", record[i][j]->c_str());
				printf("\n");
			}
			printf("\n");
			*/

			//construct paths
			if (st[len] == 1) constructSolutions(record, res, (int)record.size()-1, "");
			//if (st[len] == 1) printf("YES!\n");

			return res;
		}
Beispiel #8
0
void values(unordered_set<int> &s,int a,int b)
{
    s.insert(a);
    s.insert(b);
    if(s.size()==1) return;
    int n;
    std::vector<int> src,dst;
    std::vector<int>::iterator iti,itj;
    std::unordered_set<int> v;
    size_t lastsz=0;
    while(true){
        copy(s.begin(),s.end(),std::back_inserter(src));

        for(iti=src.begin();iti!=src.end();++iti){
            for(itj=src.begin();itj!=src.end();++itj){
                n = *iti-*itj;
                if(n>0)
                    v.insert(n);
            }
        }
        /*
        cout<<"差值[原始]:";
        std::for_each(v.begin(),v.end(),[](int n){cout<<n<<'\t';});
        cout<<endl;
        */
        src.clear();
        copy(v.begin(),v.end(),std::back_inserter(dst));
        copy(s.begin(),s.end(),std::back_inserter(src));

        std::sort(dst.begin(),dst.end());
        std::sort(src.begin(),src.end());
        //unordered_set difference
        std::vector<int> tmp(a/(a-b)+1);
        iti = std::set_difference(dst.begin(),dst.end(),src.begin(),src.end(),tmp.begin());
        tmp.resize(iti-tmp.begin());
        /*
        cout<<"差值:";
        std::for_each(tmp.begin(),tmp.end(),[](int n){cout<<n<<'\t';});
        cout<<endl;
        */
        if(tmp.empty()) break;
        s.insert(*tmp.begin());
        if(s.size()==lastsz) break;
        lastsz = s.size();

        //std::for_each(v.begin(),v.end(),[&s](int n){cout<<n<<'\t';s.insert(n);});
        v.clear();
        src.clear();
        dst.clear();
    }
}
Beispiel #9
0
void
PerceptronModel::ComputeFeaturesToUpdate(const CandidateSet &example,
                                         unordered_set<int> &
                                         gold_features_to_update,
                                         unordered_set<int> &
                                         best_scoring_features_to_update)
    const {
  // Collect gold features that are not in best-scoring candidate.
  const FeatureVector<int,double> &gold_features =
      example.GetGold().features();
  const FeatureVector<int,double> &best_scoring_features =
      example.GetBestScoring().features();

  if (DEBUG >= 2) {
    cerr << "Gold index: " << example.gold_index()
         << "; best scoring index: " << example.best_scoring_index()
         << endl;
    cerr << "Original gold features: " << gold_features << endl
         << "Original best scoring features: " << best_scoring_features << endl;
  }

  gold_features.GetNonZeroFeatures(gold_features_to_update);
  best_scoring_features.RemoveEqualFeatures(gold_features,
                                            gold_features_to_update);

  if (DEBUG >= 2) {
    cerr << "Time:" << time_.to_string() << ": new gold features: [";
    for (unordered_set<int>::const_iterator it =
             gold_features_to_update.begin();
         it != gold_features_to_update.end();
         ++it) {
      cerr << " " << *it;
    }
    cerr << "]" << endl;
  }

  best_scoring_features.GetNonZeroFeatures(best_scoring_features_to_update);
  gold_features.RemoveEqualFeatures(best_scoring_features,
                                    best_scoring_features_to_update);
  if (DEBUG >= 2) {
    cerr << "Time:" << time_.to_string() << ": new best scoring features: [";
    for (unordered_set<int>::const_iterator it =
             best_scoring_features_to_update.begin();
         it != best_scoring_features_to_update.end();
         ++it) {
      cerr << " " << *it;
    }
    cerr << "]" << endl;
  }

}
Beispiel #10
0
    bool wordBreak(string s, unordered_set<string> &dict) {
    		int n = s.size();
    		int q[n + 1];
    		memset(q, 0, sizeof(q));
    		q[0] = 1;

    		unordered_set<string>::iterator it;
    		string t;

    		for (int i = 1; i <= n; i++) {
    			for (it = dict.begin(); it != dict.end(); ++it) {

    				t = *it;
    				int j = t.size();
    				if (i < j || !q[i - j]) continue;

    				bool flag = true;
    				for (int k = j; k >= 1; k--) {
    					if (s[i - j + k - 1] != t[k - 1]) {
    						flag = false;
    						break;
    					}
    				}
    				if (flag) {
    					q[i] = 1;
    				}
    			}
    		}
    		return (q[n] == 1);
    }
Beispiel #11
0
        void dfs(string start, string &end, unordered_set<string> &dict, 
                int curL, int minL,
                vector<string> &vis, vector<string> &ret){
            if(curL > minL)
                return;

            int len = dict.begin()->size();

            for(int i = 0; i < len; i++){
                string v = start;
                char oldc = start[i];
                for(char c = 'a'; c <= 'z'; c++){
                    if(c == oldc)
                        continue;
                    v[i] = c;
                    if(v == end){
                        vis.push_back(v);
                        ret.append(vis);
                        vis.pop_back();
                        return;
                    }
                    if(dict.find(v) == dict.end())
                        continue;
                    vis.push_back(v);
                    dfs(v, end, dict, curL+1, minL, vis, ret);
                    vis.pop_back();
                }
            }

        }
Beispiel #12
0
static void manageConstructionEvent(color_ostream& out) {
    if ( handlers[EventType::CONSTRUCTION].empty() )
        return;

    unordered_set<df::construction*> constructionsNow(df::global::world->constructions.begin(), df::global::world->constructions.end());
    
    multimap<Plugin*,EventHandler> copy(handlers[EventType::CONSTRUCTION].begin(), handlers[EventType::CONSTRUCTION].end());
    for ( auto a = constructions.begin(); a != constructions.end(); a++ ) {
        df::construction* construction = *a;
        if ( constructionsNow.find(construction) != constructionsNow.end() )
            continue;
        for ( auto b = copy.begin(); b != copy.end(); b++ ) {
            EventHandler handle = (*b).second;
            handle.eventHandler(out, (void*)construction);
        }
    }

    for ( auto a = constructionsNow.begin(); a != constructionsNow.end(); a++ ) {
        df::construction* construction = *a;
        if ( constructions.find(construction) != constructions.end() )
            continue;
        for ( auto b = copy.begin(); b != copy.end(); b++ ) {
            EventHandler handle = (*b).second;
            handle.eventHandler(out, (void*)construction);
        }
    }
    
    constructions.clear();
    constructions.insert(constructionsNow.begin(), constructionsNow.end());
}
int WordBreak::wordBreak(string s, unordered_set<string> &dict) {
	static vector<string> words;

	int combination = 0;
	unordered_set<string>::iterator iter = dict.begin();

	if (s.empty())
		return false;

	while (iter != dict.end()) {
		string w = *iter;
		if (!s.compare(0, w.length(), w)) {
			words.push_back(w);

			if (s.length() == w.length()) {
				dumpWords(words);
				combination++;
			}

			combination += wordBreak(s.substr(w.length(), s.length()-w.length()), dict);

			words.pop_back();
		}

		iter++;
	}

	return combination;
}
// 双向BFS搜索
// --------                     ----------
// |       |                    |        |
// |words1 |  <---------------> | words2 |
// |       |                    |        |
// ---------                    ----------   
// 不断地从两端向中心搜索,直至搜索到中间单词temp在另一个词袋中
int searchwithDoubleBFS(unordered_set<string>& words1, unordered_set<string>& words2,
	unordered_set<string>& dict, int level) {
	
	if (words1.empty()) return 0;		
	if (words1.size() > words2.size()) 
		return searchwithDoubleBFS(words2, words1, dict, level);
	
	unordered_set<string> words3;
	for (auto it = words1.begin(); it != words1.end(); ++it) {
		string word = *it;
		for (size_t i = 0; i < word.size(); ++i) {
			int ch = word[i];
			for (int k = 0; k < 26; ++k) {
				int ch2 = 'a' + k;
				if (ch2 != ch) {
					string temp = word;
					temp[i] = ch2;
					if (words2.find(temp) != words2.end()) {
						return level+1;
					} else {
						if (dict.find(temp) != dict.end()) {
							dict.erase(temp);
							words3.insert(temp);
						}
					}
					
				}
			}
		}
	}
	return searchwithDoubleBFS(words3, words2, dict, level+1);
}
Beispiel #15
0
    int ladderLength(string start, string end, unordered_set<string> &dict) {
        int cur_steps = 0, cur_num = 1, res = -1, next_num = 0;
        queue<string> Q;
        unordered_set<string>::iterator it;
        unordered_set<string> visited;
        Q.push(start);
        while(!Q.empty()) {
            string tmp = Q.front();
            Q.pop();
            if(judge_string(tmp, end)) {
                res = (cur_num == 0 ? cur_steps + 1 : cur_steps) + 2;
                break;
            }
            for(it = dict.begin(); it != dict.end(); it++) {
                if(visited.find(*it) == dict.end() && judge_string(tmp, (string)(*it))) {
                    Q.push(*it);
                    visited.insert(*it);
                    next_num++;
                }
            }
            cur_num--;
            if(cur_num == 0) {
                cur_num = next_num;
                next_num = 0;
                cur_steps++;
            }

        }
        return res;
    }
Beispiel #16
0
 bool helper(unordered_set<string>& word1, unordered_set<string>& word2, unordered_set<string>& dict){
     if(word1.empty()) return 0;
     if(word1.size() > word2.size()) return helper(word2, word1, dict);
     for(auto v : word1) dict.erase(v);
     for(auto v : word2) dict.erase(v);
     
     ++res;
     bool reach = false;
     unordered_set<string> word3;
     for(auto it = word1.begin(); it != word1.end(); ++it){
         string word = *it;
         for(int i = 0; i < word.size(); ++i){
             char letter = word[i];
             for(int k = 0; k < 26; ++k){
                 word[i] = 'a'+k;
                 if(word2.count(word)){
                     reach = true;
                     return reach;
                 }
                 if(dict.count(word) && !reach){
                     word3.insert(word);
                 }
             }
             word[i] = letter;
         }
     }
     return reach || helper(word2, word3, dict);
 }
 /** Provide a number which is not assigned to anyone.
     @return - Return an available number. Return -1 if none is available. */
 int get() {
     if(pool.empty()) return -1;
     auto it = pool.begin();
     int res = *it;
     pool.erase(it);
     return res;
 }
Beispiel #18
0
void findLaddersDST(
	const string& start,
	const string& end,
	unordered_set<string> &dict,
	vector<string>& ladder,
	vector<vector<string> >& ladders)
{
	if (isChangable(start, end))
	{
		ladder.push_back(end);
		ladders.push_back(ladder);
		return;
	}

	unordered_set<string>::iterator it = dict.begin();
	unordered_set<string>::iterator it_end = dict.end();

	while (it != it_end)
	{
		string str = *it;

		if (isChangable(str, start))
		{
			unordered_set<string> new_dict(dict);
			vector<string> new_ladder(ladder);
			new_dict.erase(str);
			new_ladder.push_back(str);

			findLaddersDST(str, end, new_dict, new_ladder, ladders);
		}
		it++;
	}
}
 void mergeSets(unordered_set<string> &us1, unordered_set<string> &us2) {
     for (auto it = us2.begin(); it != us2.end(); ++it) {
         if (us1.find(*it) == us1.end()) {
             us1.insert(*it);
         }
     }
 }
 vector<string> wordBreak(string s, unordered_set<string> &dict) {
     TrieTreeNode *root = new TrieTreeNode();
     for (unordered_set<string>::iterator it=dict.begin(); it != dict.end(); it++) {
         addWord(root, *it);
     }
     
     vector<bool> f(s.length() + 1, false);
     f[s.length()] = true;
     for (int i=s.length() - 1; i>=0; i--) {
         int j = i;
         TrieTreeNode *currNode = root;
         unordered_map<char, TrieTreeNode*>::iterator it;
         while (j < s.length()) {
             it = currNode->sons.find(s[j]);
             if (it == currNode->sons.end()) break;
             currNode = it->second;
             if (f[j + 1] && currNode->inDict) {
                 f[i] = true; break;
             }
             j++;
         }
     }   
     vector<string> ans, words;
     dfs(0, words, ans, f, s, dict, root);
     destroyTree(root);
     return ans;
 }
 void buildMap(unordered_set<string> dict, unordered_map<string, int> &pos,
               vector<string> &words){
     for(unordered_set<string>::iterator it = dict.begin(); it != dict.end(); it++){
         words.push_back(*it);
         pos[*it] = words.size() - 1;
     }
 }
Beispiel #22
0
    bool wordBreak(string s, unordered_set<string> &dict) {
		int slen=s.size();
		for(int i=0;i<slen;i++)
			memset(dp[i],0,sizeof(bool)*slen);
		for(int i=0;i<s.size();i++)
		{
			for(auto j=dict.begin();j!=dict.end();++j)
			{
				//string tmp=*j;
				if((string)s[i] == (*j)) 
				{
					dp[i][i]=1;
					break;
				}
			}
		}
		for(int len=2;len<=s.size();len++)
		{
			for(int i=0;i<s.size();i++)
			{
				int j=i+len-1;
				if(j>=s.size())
					continue;
				for(int k=i;k<j;k++)
				{
					if(dp[i][k]&&dp[k+1][j])
					{
						dp[i][j]=1;
						break;
					}
				}
			}
		}
		return dp[0][slen-1];
    }
// Act like BFS, but I don't know how to store segmented words and print them out.
int WordBreak::wordBreak_iterative(string s, unordered_set<string> &dict) {
	int combination = 0;
	vector<string> words;
	stack<string> todo;

	todo.push(s);
	while (!todo.empty()) {
		string s = todo.top();
		todo.pop();

		unordered_set<string>::iterator iter = dict.begin();
		while (iter != dict.end()) {
			string w = *iter;
			if (!s.compare(0, w.length(), w)) {

				if (s.length() == w.length()) {
					dumpWords(words);
					combination++;
				} else {
					todo.push(s.substr(w.length(), s.length()-w.length()));
				}
			}
			iter++;
		}
	}

	return combination;
}
Beispiel #24
0
    // determine if s can be segmented and calculate the effective length of the substring.
    bool canWordBreak(string& s, unordered_set<string>& wordDict) {
        if (wordDict.empty())
            return false;
        len = s.size(), min_len = max_len = wordDict.begin()->size();
        int temp;
        for (auto& word : wordDict)
        {
            temp = word.size();
            if (temp > max_len)
                max_len = temp;
            else if (temp < min_len)
                min_len = temp;
        }

        vector<bool> flag(len + 1);
        flag[len] = true;
        for (int i = len - 1; i >= 0; --i)
            for (int j = min_len; j <= min(max_len, len - i); ++j)
                if (flag[i + j] && wordDict.find(s.substr(i, j)) != wordDict.end())
                {
                    flag[i] = true;
                    break;
                }

        return flag[0];
    }
Beispiel #25
0
 bool wordBreak(string s, unordered_set<string> &dict) {
     // Note: The Solution object is instantiated only once and is reused by each test case.
     int len = s.length();
     bool tmpRes[len+1];
     int i;
     int tmpLen=0;
     tmpRes[0]=true;
     unordered_set<string>::iterator p;
     string tmpStr="";
     //s[1:n-1] can be break?
     for(i=1;i<=len;i++){ 
         tmpRes[i] = false;
         for(p=dict.begin();p!=dict.end();p++){
             tmpStr=*p;
             tmpLen = tmpStr.length();
             if(tmpLen > i) continue;
             else{
                 if(s.compare(i-tmpLen,tmpLen,tmpStr) == 0){
                     tmpRes[i] = tmpRes[i-tmpLen];
                     if(tmpRes[i] == true) break;
                 }
             }
         }
     }
     return tmpRes[len];
 }
    void recursiveFindLadder(vector<string>& ladder, unordered_set<string>& pool) {
        if (pool.empty()) {
            return;
        }
        
        printLadder(ladder);
        printPool(pool);
        printf("\n");

        string beginWord = ladder[ladder.size()-1];

        vector<string> candidates;
        for (unordered_set<string>::iterator it = pool.begin(); it != pool.end(); ++it) {
            int diffCount = diffWord(beginWord, *it, NULL);
            if (diffCount == 1) {
                candidates.push_back(*it);
            }
        }
        
        for (int i=0; i< candidates.size(); ++i) {
            ladder.push_back(candidates[i]);
            pool.erase(candidates[i]);
            recursiveFindLadder(ladder, pool);
        }
    }
Beispiel #27
0
 vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
     allstr.clear();
     res.clear();
     
     if (dict.size() == 0) return res;
     if (start == end) {
         vector<string> justone(1, start);
         res.push_back(justone);
         return  res;
     }
     
     allstr.push_back(make_pair(start, 1));
     allstr.push_back(make_pair(end, 0));
     
     for (unordered_set<string>::iterator pos = dict.begin(); pos != dict.end(); ++ pos) {
         if (*pos != start && *pos != end) {
             allstr.push_back(make_pair(*pos, 0));
         }
     }
     
     _makeLinks();
     
     int step = _ladderLen();
     
     stk.clear();
     stk.push_back(1);
     _DFS(step);
     return res;
 }
Beispiel #28
0
 vector<string> removeInvalidParentheses(string s) {
     int leftBracket = 0, rightBracket = 0;
     checkBracket(s, leftBracket, rightBracket);
     string myans;
     dfs(s, myans, 0, leftBracket, rightBracket, 0);
     return vector<string>(ans.begin(), ans.end());
 }
Beispiel #29
0
        int minLength(string &start, string &end, unordered_set<string> &dict){
            int n = dict.size();
            if(n == 0)
                return 0;
            int len = dict.begin()->size();

            queue<string> q;
            q.push(start);
            map<string, int> vis;
            map<string, string> pre;
            vis[start] = 0;
            while(!q.empty()){
                string u = q.front();
                q.pop();
                for(int i = 0; i < len; i++){
                    string v = u;
                    char oldc = u[i];
                    for(char c = 'a'; c <= 'z'; c++){
                        if(c == oldc)
                            continue;
                        v[i] = c;
                        if(v == end){
                            return vis[u] + 1;
                        }
                        if(dict.find(v) == dict.end())
                            continue;
                        if(vis.find(v) == vis.end()){
                            vis[v] = vis[u] + 1; 
                            q.push(v);
                        }
                    }
                }
            }
            return 0;
        }
Beispiel #30
0
 //If there is no '&' before set, the time cost will be tripled;
 int ladderLength(unordered_set<string>& bList, unordered_set<string>& eList, unordered_set<string>& wordList, int len)
 {
     if(bList.empty())
         return 0;
     if(bList.size() > eList.size())
         return ladderLength(eList, bList, wordList, len);
     unordered_set<string> tmpList;
     for(auto it=bList.begin(); it!=bList.end(); it++)
     {
         string cur = *it;
         for(int i=0; i<cur.size(); i++)
         {
             char c0 = cur[i];
             for(char c='a'; c<='z'; c++)
             {
                 cur[i]=c;
                 if(eList.count(cur)) return len+1;
                 if(wordList.count(cur))
                 {
                     tmpList.insert(cur);
                     wordList.erase(cur);
                 }
             }
             cur[i] = c0;
         }
     }
     return ladderLength(tmpList, eList, wordList, len+1);
 }