むかし書いたやつが発掘されたので供養というか。すっかりC#忘れてるので読解に苦労しました。むかしの自分すげぇな
using System; using System.Linq; using System.Collections.Generic; public class Program{ public static void Main(){ //はじめに var test1 = new int[,]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; var test2 = test1.Clone() as int[,]; //test1と同値をもつ2次元配列 var set1 = new HashSet<int[,]>(); set1.Add(test1); Console.WriteLine(set1.Contains(test2)); //test1とtest2はそもそも別オブジェクトなので当然 var unziped1 = UnZip(test1); //一次元配列に展開 var unziped2 = UnZip(test2); //同じく var set2 = new HashSet<int[]>(); set2.Add(unziped1); Console.WriteLine(set2.Contains(unziped2)); //当然 /////////////////////////////////////////////////// //解法1 //値型に何らかの形で直してやるパターン //文字列 var str1 = ToStr(test1); var str2 = ToStr(test2); var set3 = new HashSet<string>(); set3.Add(str1); Console.WriteLine(set3.Contains(str2)); //文字列に直せばいいけどstringへの変換がクソ遅い //longとかそのへん var longed1 = ToLong(test1); var longed2 = ToLong(test2); var set4 = new HashSet<long>(); set4.Add(longed1); Console.WriteLine(set4.Contains(longed2)); //文字列よりはマシだけど一桁ずつに情報をもたせているので9種類しか持てないし限定的すぎる(1と11が含まれていたらもう復元できない・0が先頭になることはない) //あるいは数値とインデックスでHashCode的なのをうまく一意に生成できれば可能っぽいけど ////////////////////////////////////////////////// //解法2 //愚直に舐めていくパターン set1.Clear(); bool flag; var _any1 = new int[,]{{2, 3, 4}, {5, 6, 7}, {8, 9, 1}}; var _any2 = new int[,]{{3, 4, 5}, {6, 7, 8}, {9, 1, 2}}; var _any3 = new int[,]{{9, 8, 7}, {6, 5, 4}, {3, 2, 1}}; //...このあと_any1000000000くらいまで続くと想定 set1.Add(_any1); set1.Add(_any2); set1.Add(_any3); //...このあと_any1000000000くらいまで続く想定 set1.Add(test1); //set1にtest2と同じ要素をもつものが含まれているかどうか調べたい var b = false; foreach(var s in set1){ if(Check(s, test2)){ b = true; break; } } Console.WriteLine(b ? "ありました" : "ねぇよ帰れクソが"); //この方法だと見つけたいターゲットがリストの最後のほうにあったときに探索に時間がかかる。Linqもゴテゴテなのでたぶん遅い } public static int[] UnZip(int[,] moto){ return moto.Cast<int>().ToArray(); var h = moto.GetLength(0); var w = moto.GetLength(1); var len = h*w; var ret = new int[len]; for(int i=0; i<h; i++){ for(int j=0; j<w; j++){ ret[i*w+j] = moto[i,j]; } } return ret; } public static string ToStr(int[,] moto){ var h = moto.GetLength(0); var w = moto.GetLength(1); var sb = new System.Text.StringBuilder(); for(int i=0; i<h; i++){ for(int j=0; j<w; j++){ sb.Append(moto[i,j].ToString()); } } return sb.ToString(); } public static long ToLong(int[,] moto){ var h = moto.GetLength(0); var w = moto.GetLength(1); long ret = default(long); for(int i=0; i<h; i++){ for(int j=0; j<w; j++){ var count = i*h+j; ret+=moto[i,j]*(long)Math.Pow(10, h*w-count-1); } } return ret; } public static bool Check(int[,] me, int[,] target){ //meとtargetが同じ次元数かつ同じ要素数であるか var unko = me.Rank==target.Rank&&Enumerable.Range(0, me.Rank).All(dim=>me.GetLength(dim)==target.GetLength(dim)); if(!unko) return false; return me.Cast<int>().SequenceEqual(target.Cast<int>()); } }