///教育部工科技藝競賽 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.");
}
}
}