挑战编程:最小操作数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Matthew_Fan/article/details/9502059
题目详情

给了A、B两个单词和一个单词集合Dict,每个的长度都相同。我们希望通过若干次操作把单词A变成单词B,每次操作可以改变单词中的一个字母,同时,新产生的单词必须是在给定的单词集合Dict中。求所有行得通步数最少的修改方法。


   举个例子如下:

Given:

   A = "hit"

   B = "cog"

   Dict = ["hot","dot","dog","lot","log"]

Return

 [

   ["hit","hot","dot","dog","cog"],

   ["hit","hot","lot","log","cog"]

 ]


    即把字符串A = "hit"转变成字符串B = "cog",有以下两种可能:

  1. "hit" -> "hot" ->  "dot" ->  "dog" -> "cog";
  2. "hit" ->  "hot" ->  "lot" ->  "log"  ->"cog"。


最后一次尝试还是超时了,同志还需努力呀!


代码如下:

#include <string>
#include <vector>
#include <iostream>
#include <set>
#include <map>
#include <algorithm>
using namespace std;

static int num = 0;

class Solution
{
public:
	vector<vector<string>> findLadders(string start, string end, set<string>& dict)
	{
		// 清理数据
		init(); 

		vector<vector<string>> minResult;

		if (start != end)
		{
			createDictionary(start, end, dict);
			// 获取全部转化情况
			minimumOperands(start, end);
			//minimumOperands(end, start);
			// 提取操作数最少的情况
			getMinLadders(minResult);
		}
		cout << "operands totals is " << num << endl;
		return minResult;
	}

private:
	void getMinLadders(vector<vector<string>>& minResult)
	{
		for (vector<vector<string>>::iterator itr = m_result.begin(); itr != m_result.end(); itr ++)
		{
			if ((*itr).size() == iMinimumOperands)
				minResult.push_back(*itr);
		}
	}

	void init()
	{
		iMinimumOperands = 0;
		for (int i = 0; i < m_result.size(); i ++)
		{
			m_result[i].clear();
		}
		m_result.clear();
		m_resultItem.clear();
	}

	// 获取不相似数
	int compareCharacter(string strDesk, string strSource)
	{
		int totals = 0;
		for (int i = 0; i < strDesk.size(); i ++)
		{
			if (strDesk[i] != strSource[i])
			{
				totals ++;
			}
		}
		return totals;
	}

	// 判断是否包含字符串
	bool isContainChars(string strDesk, vector<string> vectorSource)
	{
		for (vector<string>::iterator iter = vectorSource.begin(); iter != vectorSource.end(); iter ++)
		{
			if (*iter == strDesk)
			{
				return true;
			}
		}
		return false;
	}

	// 创建字典表
	bool createDictionary(string strFrist, string strTarget, set<string>& strDict)
	{
		//m_dict.insert(map<string, set<string>>::value_type(index, x));
		set<string> dictElement;
		for (set<string>::iterator itr = strDict.begin(); itr != strDict.end(); itr ++)
		{
			m_dict.insert(map<string, set<string>>::value_type(*itr, dictElement));
		}
		m_dict.insert(map<string, set<string>>::value_type(strFrist, dictElement));
		m_dict.insert(map<string, set<string>>::value_type(strTarget, dictElement));


		for (set<string>::iterator itr = strDict.begin(); itr != strDict.end(); itr ++)
		{
			map<string, set<string>>::iterator iter;
			for (iter = m_dict.begin(); iter != m_dict.end(); iter ++)
			{
				if (compareCharacter(iter->first, *itr) == 1)
				{
					iter->second.insert(*itr);
				}
			}
		}
		m_endCharsDict = m_dict.find(strTarget)->second;
		
		return true;
	}

	// 查找
	//set<string>::iterator GetFristItr(const set<string>& setDesk, set<string>::iterator &_iter)
	//{
	//	_iter = setDesk.begin();

	//	for (set<string>::iterator iter = setDesk.begin(); iter != setDesk.end(); iter ++)
	//	{
	//		if (m_endCharsDict.find(*iter) != m_endCharsDict.end())
	//		{
	//			_iter = iter;
	//			break;
	//		}
	//	}
	//	return _iter;
	//}

	int minimumOperands(string strFrist, string strTarget/*, set<string>& strDict*/)
	{
		string key = strFrist;
		m_resultItem.push_back(key);
		set<string> strDict = m_dict.find(strFrist)->second;
		set<string>::iterator itr = strDict.begin;
		//GetFristItr(strDict, itr);
		for (; itr != strDict.end(); itr ++)
		{
			if (isContainChars(*itr, m_resultItem))
				continue;
		
			if (iMinimumOperands < m_resultItem.size() + 1 && iMinimumOperands != 0)
			{
				m_resultItem.erase(m_resultItem.end() - 1);
				return 1;
			}

			int flag = compareCharacter(key, strTarget);
			num ++;

			if (flag == 0 || flag == 1)
			{
				// 获取最小的操作数
				if (iMinimumOperands > m_resultItem.size() + 1 || iMinimumOperands == 0)
					iMinimumOperands = m_resultItem.size() + 1;

				if (flag == 1)   
				{
					// 添加结尾字段
					m_resultItem.push_back(strTarget);
				}

				// 添加到操作族中
				m_result.push_back(m_resultItem);

				// 移除尾部,返回上一级继续处理
				if (flag == 1)
				{
					m_resultItem.erase(m_resultItem.end() - 1);
				}
				m_resultItem.erase(m_resultItem.end() - 1);

				return 1;
			}
			
			if (minimumOperands(*itr, strTarget) == 1)
				continue;

		}
		// 移除尾部,返回上一级继续处理
		m_resultItem.erase(m_resultItem.end() - 1);
		
		/*for (vector<string>::iterator iter = m_resultItem.begin(); iter != m_resultItem.end(); iter ++)
		{
			cout << *iter << ",";
		}
		cout << endl;*/
		
		return iMinimumOperands;
	}

private:
	vector<string> m_resultItem;            // 临时存储每一组操作顺序
	vector<vector<string>> m_result;        // 存放所有成功转化的操作族
	map<string, set<string>> m_dict;                // 字典表
	set<string> m_endCharsDict;						// 最后的字符的字典表
	int  iMinimumOperands;                          // 记录最小的操作数
};
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{   
	//
	string dict[599] = {"abe", "ace", "act", "ada", "ado", "ads", "adz", "aft", "age", "ago", "aha", "aid", "ail", "aim", "air", "ala", "alb", "ale", "ali", "all", "amp", "amy", "ana", "and", "ani", "ann", "ant", "any", "ape", "apr", "ara", "arc", "are", "ark", "arm", "art", "ash", "ask", "asp", "ass", "ate", "ats", "aug", "auk", "ava", "ave", "awe", "awl", "axe", "aye", "baa", "bad", "bag", "bah", "ban", "bar", "bat", "bay", "bed", "bee", "bet", "bib", "bid", "big", "bin", "bit", "bmw", "boa", "bob", "bog", "boo", "bow", "box", "boy", "brr", "btu", "bud", "bug", "bum", "bun", "bur", "bus", "but", "buy", "bye", "cab", "cad", "cal", "can", "cap", "cat", "caw", "cet", "chi", "cid", "cob", "cod", "cog", "col", "com", "con", "coo", "cot", "cox", "coy", "cry", "cub", "cup", "dab", "dan", "day", "dec", "dee", "del", "dem", "den", "dew", "did", "die", "dig", "dim", "din", "dip", "dis", "dix", "doc", "doe", "dog", "don", "dot", "dow", "due", "dug", "duh", "dun", "duo", "dye", "ear", "eat", "eco", "eel", "ego", "elf", "ell", "elm", "end", "era", "ere", "erg", "err", "eva", "eve", "ewe", "eye", "fad", "fan", "far", "fat", "fax", "fay", "feb", "fed", "fee", "fen", "few", "fey", "fez", "fib", "fie", "fig", "fin", "fir", "fit", "fix", "fla", "flo", "flu", "fob", "foe", "fog", "fop", "for", "fox", "fry", "fun", "fur", "gad", "gag", "gal", "gap", "gas", "gay", "gee", "gel", "gem", "geo", "ger", "get", "gig", "gil", "gin", "gob", "god", "gog", "goo", "gos", "got", "gte", "gum", "gun", "gut", "guy", "gym", "gyp", "hag", "hah", "hal", "ham", "han", "has", "haw", "hay", "hem", "hen", "hep", "her", "hew", "hex", "hey", "hid", "hie", "him", "hip", "his", "hit", "hob", "hod", "hoe", "hog", "hon", "hop", "hot", "hub", "hue", "hug", "hui", "hum", "hun", "hus", "hut", "ian", "ibm", "ibo", "ifs", "ike", "ila", "ilk", "ill", "imp", "ina", "ind", "inn", "ins", "ion", "ire", "irk", "ism", "ito", "its", "iva", "ivy", "jab", "jag", "jam", "jan", "jar", "jaw", "jay", "jed", "jib", "jig", "jim", "job", "joe", "jog", "jot", "joy", "jut", "kay", "keg", "ken", "kid", "kin", "kip", "kit", "lab", "lad", "lag", "lao", "lap", "lax", "lay", "led", "leg", "lei", "len", "let", "lid", "lie", "lin", "lit", "liz", "lob", "log", "lon", "lop", "lot", "low", "ltd", "lug", "luz", "lye", "lyx", "mac", "mad", "mai", "maj", "man", "mao", "map", "mas", "maw", "max", "may", "mci", "meg", "mel", "mes", "met", "mew", "mgm", "mia", "mid", "mig", "mil", "min", "mir", "mix", "mob", "mod", "moe", "mom", "mon", "mow", "mug", "mum", "nag", "nam", "nan", "nap", "nat", "ned", "net", "nev", "new", "nil", "nix", "nod", "noh", "non", "nor", "not", "nov", "now", "nub", "nun", "nut", "oaf", "oak", "oar", "oct", "odd", "ode", "off", "oft", "oho", "ohs", "oil", "ola", "old", "ono", "opt", "ora", "orb", "ore", "our", "out", "ova", "owe", "owl", "own", "pad", "pal", "pam", "pan", "pap", "par", "pas", "pat", "paw", "pay", "pea", "pei", "per", "pet", "pew", "pie", "pig", "pin", "pip", "pit", "ply", "pod", "poe", "poi", "pol", "pop", "pot", "pox", "pro", "pry", "pub", "pug", "pun", "pup", "pus", "put", "pyx", "qom", "ram", "ran", "rap", "ray", "red", "ref", "rep", "rev", "rex", "rib", "rid", "rig", "rim", "rio", "rip", "rob", "rod", "ron", "row", "roy", "rte", "rub", "rue", "rum", "rut", "rye", "sac", "sad", "sag", "sal", "sam", "san", "sap", "saw", "sax", "sec", "see", "sen", "set", "sew", "sgt", "she", "shy", "sic", "sid", "sin", "sip", "sis", "six", "ski", "sky", 
		"sly", "sob", "sol", "son", "sop", "sow", "sox", "soy", "spy", "stu", "sty", "sub", "sue", "sui", "sum", "sun", "sup", "tab", "tad", "tag", "tam", "tan", "tao", "tap", "tar", "tat", "tax", "ted", "tee", "ten", "tex", "tho", "thy", "tia", "tie", "tin", "tit", "tod", "toe", "tog", "tom", "ton", "too", "top", "tot", "tow", "toy", "try", "tub", "tug", "tun", "tut", "tux", "two", "ump", "use", "val", "van", "vat", "vet", "via", "vic", "vie", "vim", "vow", "wac", "wad", "wag", "wan", "war", "was", "wax", "way", "web", "wed", "wei", "wen", "wet", "who", "why", "wig", "win", "wis", "wit", "woe", "won", "woo", "wot", "wry", "wyo", "yak", "yam", "yap", "yaw", "yea", "yep", "yet", "yew", "yip", "yon", "you", "yum", "yup", "zed", "zen", "zip", "zit", "zoe", "zoo"};
	set<string> strDict;
	/*strDict.insert("a");
	strDict.insert("b");
	strDict.insert("c");*/
	/*strDict.insert("hot");
	strDict.insert("dot");
	strDict.insert("dog");
	strDict.insert("lot");
	strDict.insert("log");*/
	for (int i = 0; i < 599; i ++)
	{
		strDict.insert(dict[i]);
	}


	Solution solutin;
	//vector<vector<string>> result = solutin.findLadders("hit","cog",/*"cet", "ism",*/ strDict);
	vector<vector<string>> result = solutin.findLadders("cet", "ism", strDict);

	for (vector<vector<string>>::iterator itr = result.begin(); itr != result.end(); itr ++)
	{
		for (int i = 0; i < (*itr).size(); i ++)
		{
			printf("%s",(*itr)[i].data());
		}
		printf("\n");

	}
	cout << "Ok" << endl; 
	getchar();

	return 0;
} 
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。


猜你喜欢

转载自blog.csdn.net/Matthew_Fan/article/details/9502059