演算法樂趣之窮舉搜尋例項:Google方程式;
阿新 • • 發佈:2019-01-07
如題:有一個有字元組成的等式:WWWDOT-GOOGLE = DOTCOM,每個字元代表一個0-9之間的數字,WWWDOT、GOOGLE和DOTCOM都是合法的數字,不能以0開頭,請找出一組字元和數字的對應關係,使得它們互相轉換,並且替換後的數字都能滿足等式。
總共可能性:10*9*8*······*2(不考慮0是開頭數字的情況)-3*9*8*····*2(所有0是開頭數字的情況,W、G、D可能為0)=2540160;
資料模型
1、建立字元資料模型,由字元,代表數值,以及是否為高位組成;
public class TagCharItem { public char C; public int Value; public bool Leading; }
2、建立數值資料模型,有是否被佔用,數字組成;
public class TagCharValue
{
public bool Used;
public int Value;
}
3、核心演算法:使用遞迴的方式進行組合列舉;
public void SearchingResult(TagCharItem[] tagCharItems, TagCharValue[] tagCharValues, int index) { if (index == tagCharItems.Length) { IsOK(tagCharItems); return; } for (int i = 0; i < tagCharValues.Length; i++) { if (IsValueValid(tagCharItems[index], tagCharValues[i])) { tagCharValues[i].Used = true; tagCharItems[index].Value = tagCharValues[i].Value; SearchingResult(tagCharItems, tagCharValues, index + 1); tagCharValues[i].Used = false; } } }
4、所有程式碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FunOfAlgorithms.Chapter03 { public class GoogleX { public void Main() { TagCharItem[] tagCharItem = { new TagCharItem() { C = 'W', Value = -1, Leading = true },// new TagCharItem() { C = 'D', Value = -1, Leading = true },// new TagCharItem() { C = 'O', Value = -1, Leading = false }, new TagCharItem() { C = 'T', Value = -1, Leading = false }, new TagCharItem() { C = 'G', Value = -1, Leading = true },// new TagCharItem() { C = 'L', Value = -1, Leading = false }, new TagCharItem() { C = 'E', Value = -1, Leading = false }, new TagCharItem() { C = 'C', Value = -1, Leading = false }, new TagCharItem() { C = 'M', Value = -1, Leading = false } }; TagCharValue[] tagCharValues = { new TagCharValue(){ Used = false, Value = 0}, new TagCharValue(){ Used = false, Value = 1}, new TagCharValue(){ Used = false, Value = 2}, new TagCharValue(){ Used = false, Value = 3}, new TagCharValue(){ Used = false, Value = 4}, new TagCharValue(){ Used = false, Value = 5}, new TagCharValue(){ Used = false, Value = 6}, new TagCharValue(){ Used = false, Value = 7}, new TagCharValue(){ Used = false, Value = 8}, new TagCharValue(){ Used = false, Value = 9}, }; SearchingResult(tagCharItem, tagCharValues, 0); } /// <summary> /// 使用遞迴方式進行組合列舉 /// </summary> /// <param name="tagCharItems"></param> /// <param name="tagCharValues"></param> /// <param name="index"></param> public void SearchingResult(TagCharItem[] tagCharItems, TagCharValue[] tagCharValues, int index) { if (index == tagCharItems.Length) { IsOK(tagCharItems); return; } for (int i = 0; i < tagCharValues.Length; i++) { if (IsValueValid(tagCharItems[index], tagCharValues[i])) { tagCharValues[i].Used = true; tagCharItems[index].Value = tagCharValues[i].Value; SearchingResult(tagCharItems, tagCharValues, index + 1); tagCharValues[i].Used = false; } } } /// <summary> /// 判定資料是否有效,是否可以被賦值 /// </summary> /// <param name="tagCharItem"></param> /// <param name="tagCharValue"></param> /// <returns></returns> public bool IsValueValid(TagCharItem tagCharItem, TagCharValue tagCharValue) { if (tagCharItem.Leading) { if (!tagCharValue.Used) { if (tagCharValue.Value == 0) { return false; } else { return true; } } else { return false; } } else { if (!tagCharValue.Used) { return true; } else { return false; } } } /// <summary> /// 判定現有資料是否符合題目要求 /// </summary> /// <param name="tagCharItems"></param> public void IsOK(TagCharItem[] tagCharItems) { string WWWDOT = "WWWDOT"; ReplacaMethods(ref WWWDOT, tagCharItems); int _WWWDOT = Convert.ToInt32(WWWDOT); string GOOGLE = "GOOGLE"; ReplacaMethods(ref GOOGLE, tagCharItems); int _GOOGLE = Convert.ToInt32(GOOGLE); string DOTCOM = "DOTCOM"; ReplacaMethods(ref DOTCOM, tagCharItems); int _DOTCOM = Convert.ToInt32(DOTCOM); if (_WWWDOT - _GOOGLE == _DOTCOM) { Console.WriteLine($"WWWDOT = {WWWDOT},GOOGLE = {GOOGLE},DOTCOM = {DOTCOM}"); } } public void ReplacaMethods(ref string Example, TagCharItem[] tagCharItems) { for (int i = 0; i < tagCharItems.Length; i++) { Example = Example.Replace(tagCharItems[i].C.ToString(), tagCharItems[i].Value.ToString()); } } } public class TagCharItem { public char C; public int Value; public bool Leading; } public class TagCharValue { public bool Used; public int Value; }
演算法結果:
WWWDOT = 777589,GOOGLE = 188103,DOTCOM = 589486
WWWDOT = 777589,GOOGLE = 188106,DOTCOM = 589483
總結:該核心演算法時一種解決字元方程問題的通用演算法,遇見不同問題時,組合不同傳入資料,修改資料判定方法、資料有效性方法即可;