///教育部工科技藝競賽 109 年第六題 具容錯的門檻設定之圖形標型(Pattern)搜尋 ///漆家豪 於 海青工商 2024/2/23 using System; using System.IO; using System.Text; namespace BinArrayReader { class Program { public const int BITS = 8; public const string MARK = "0123456789ABCDEF"; public static readonly string[] BIN = {"0000","0001","0010","0011","0100","0101","0110","0111", "1000","1001","1010","1011","1100","1101","1110","1111" }; /// /// 檢查 p1 圖案是否在 map 圖案內 /// /// 主圖案 /// 檢查之圖案 /// 主圖案起始列座標 /// 主圖案起始行座標 /// 容錯數量 /// 若 p1 在 map 圖案內傳回真 public static bool checkGraphic(string[] map, string[] p1, int y , int x , int numFaults) { int i, j, k = 0; if((y+p1.Length > map.Length) || (x + p1[0].Length > map[0].Length)) { return (false); } for(i = 1; i < p1.Length; i++) { for(j =0; j < p1[0].Length; j++) { k += (map[i + y].Substring(x + j, 1) == p1[i].Substring(j, 1) ? 0 : 1); } } return (k <= numFaults); } /// /// 讀取檔案,並設定圖案寬、高及轉成 2 進制字串放到 map /// /// 讀取的黨名 /// 圖案寬度 /// 圖案高度 /// 圖案轉成2 進制文字陣列 public static void ReadFile(string filename, ref int width, ref int height, ref string[] map) { filename += (filename.ToUpper().Contains(".") ? "" : ".Txt");//為文字檔加上 .Txt try { string[] lines = File.ReadAllLines("../../../" + filename);//檔案位置在專案資料夾根部 string[] sizeValues = lines[0].Split(' '); width = int.Parse(sizeValues[0], System.Globalization.NumberStyles.HexNumber) / BITS; height = int.Parse(sizeValues[1], System.Globalization.NumberStyles.HexNumber); map = new string[height]; for (int i = 1; i <= height; i++) { string[] hexValues = lines[i].Trim().Split(' '); map[i - 1] = ""; for (int j = 0; j < hexValues.Length; j++) { map[i-1] += BIN[MARK.IndexOf(hexValues[j].Substring(0,1))] + BIN[MARK.IndexOf(hexValues[j].Substring(1, 1))]; } } } catch (Exception ex) { Console.WriteLine($"An error occurred while reading the file: {ex.Message}"); } } static void Main(string[] args) { Console.Write("Enter org filename:"); string orgName = Console.ReadLine(); Console.Write("Enter pattern filename:"); string p1Name = Console.ReadLine(); Console.Write("Enter Number of faults:"); int numFaults = int.Parse(Console.ReadLine()); int orgWidth = 0, orgHeight = 0; string [] map = new string[0]; ReadFile(orgName, ref orgWidth, ref orgHeight, ref map); //讀取原圖形 string[] p1 = new string[0]; int p1Width = 0, p1Height = 0; ReadFile(p1Name, ref p1Width, ref p1Height, ref p1); //讀取標的物 int u=0; for (int i = 0; i < map.Length;i++) { if ((u = map[i].IndexOf(p1[0], u)) >= 0)//檢查第一列 { if (checkGraphic(map, p1, i, u, numFaults))//檢查 p1 是否在 map 內 { Console.WriteLine($"\nx1:{u}, y1:{i} x2:{u + p1[0].Length}, y2:{i + p1.Length}"); return; } else { i--;//同一列繼續往後找 u++; } } else u = 0;//找不到則歸零 } Console.WriteLine("\nNo match."); } } }