การดูว่าการกำหนดค่ากริดที่แน่นอนตรงกับสูตรที่กำหนดนั้นง่ายไหมถ้าคุณเข้ารหัสกริด 3x3 เป็นสตริงและใช้การจับคู่นิพจน์ปกติ การเร่งความเร็วการค้นหาเป็นเรื่องที่แตกต่างกันซึ่งฉันจะพูดถึงในตอนท้าย อ่านต่อเพื่อรับข้อมูลเพิ่มเติม
ขั้นตอนที่ 1) เข้ารหัสตารางเป็นสตริง
เพียงให้รหัสตัวอักษรกับเซลล์แต่ละประเภทและเชื่อมทุกอย่างเข้าด้วยกันตามลำดับนี้:
123
456 => 123456789
789
และเป็นตัวอย่างที่เป็นรูปธรรมมากขึ้นพิจารณาสูตรไม้ที่ W หมายถึงไม้และ E เป็นเซลล์ว่าง (คุณสามารถใช้ถ่านที่ว่างเปล่า '):
EEE
WEE => EEEWEEWEE
WEE
ขั้นตอนที่ 2) จับคู่สูตรโดยใช้นิพจน์ปกติ (หรือสตริงมีส่วนประมวลผลเล็กน้อยกับข้อมูล)
ต่อจากตัวอย่างด้านบนแม้ว่าเราจะย้ายขบวนไปมารอบ ๆ แต่ก็ยังมีรูปแบบในสายอักขระ (WE เบาะด้วย E ทั้งสองด้าน):
EEW
EEW => EEWEEWEEE
EEE
ดังนั้นไม่ว่าคุณจะขยับคันโยกไปรอบ ๆ ที่ใดมันจะยังคงตรงกับนิพจน์ทั่วไปต่อไปนี้: /^E*WEEWE*$/
นิพจน์ทั่วไปยังช่วยให้คุณสามารถดำเนินการตามเงื่อนไขที่คุณกล่าวถึง ตัวอย่างเช่น (สูตรที่ทำขึ้น) หากคุณต้องการ pickaxe ที่ทำจากเหล็กหรือหินเพื่อให้ผลลัพธ์เดียวกันเช่น:
III SSS
EWE or EWE
EWE EWE
คุณสามารถรวมทั้งสองอย่างเข้ากับนิพจน์ทั่วไป: /^(III)|(SSS)EWEEWE$/
นอกจากนี้ยังสามารถเพิ่มการพลิกในแนวนอนได้เช่นกัน (โดยใช้ตัวดำเนินการ | ด้วย)
แก้ไข: อย่างไรก็ตามส่วน regex ไม่จำเป็นอย่างเคร่งครัด มันเป็นวิธีเดียวในการสรุปปัญหาในนิพจน์เดียว แต่สำหรับปัญหาตำแหน่งตัวแปรคุณสามารถตัดทอนกริดสตริงของช่องว่างภายในช่องว่างใด ๆ (หรือ E ในตัวอย่างนี้) และทำ String.Contains () และสำหรับปัญหาส่วนผสมหลายอย่างหรือสูตรอาหารที่ทำมิเรอร์คุณสามารถจัดการได้ทั้งหมดเป็นสูตรหลาย ๆ สูตร (เช่นแยกต่างหาก) ด้วยผลลัพธ์เดียวกัน
ขั้นตอนที่ 3) เร่งการค้นหา
สำหรับการลดการค้นหาคุณจะต้องสร้างโครงสร้างข้อมูลบางอย่างเพื่อจัดกลุ่มสูตรอาหารเข้าด้วยกันและช่วยในการค้นหา การรักษากริดเป็นสตริงมีข้อดีบางประการเช่นกัน:
คุณสามารถกำหนด "ความยาว" ของสูตรอาหารว่าเป็นระยะห่างระหว่างอักขระที่ไม่ว่างตัวแรกและอักขระที่ไม่ว่างเปล่าตัวสุดท้าย ง่ายๆTrim().Length()
จะให้ข้อมูลนี้กับคุณ ตำรับอาหารสามารถจัดกลุ่มตามความยาวและเก็บไว้ในพจนานุกรม
หรือ
คำนิยามทางเลือกของ "ความยาว" อาจเป็นจำนวนของอักขระที่ไม่ว่างเปล่า ไม่มีอะไรเปลี่ยนแปลง คุณสามารถจัดกลุ่มสูตรอาหารตามเกณฑ์นี้ด้วย
หากจุดที่ 1 ไม่เพียงพอสูตรอาหารอาจถูกจัดกลุ่มตามประเภทของส่วนผสมแรกที่ปรากฏในสูตร นี่จะง่ายเหมือนการทำTrim().CharAt(0)
(และการป้องกันการตัดทำให้สตริงว่าง)
ตัวอย่างเช่นคุณจะเก็บสูตรไว้ใน:
Dictionary<int, Dictionary<char, List<string>>> _recipes;
และทำการค้นหาตามที่ต้องการ:
// A string encode of your current grid configuration
string grid;
// Get length and first char in our grid
string trim = grid.Trim();
int length = trim.Length();
char firstChar = length==0 ? ' ' : trim[0];
foreach(string recipe in _recipes[length][firstChar])
{
// Check for a match with the recipe
if(Regex.Match(grid, recipe))
{
// We found a matching recipe, do something with it
}
}