none
如何判斷一組數字存在於數字陣列當中 RRS feed

  • 問題

  • 請問各位前輩:

    目前有個疑問想向各位請教, 如果想要判斷一組數字是否存在於某個二維陣列當中,例如:[1,2] 是否存在於 int[,] comparedArray= new int[,] {{0,0} {0,1} {1,1} {1,2}...} 那要怎麼做比較好呢?

    我想了一些比較笨的方法例如:

    for (int i = 0; i< comparedArray.getLength(0); i++)
        for (int j = 0 ; j< comparedArray.getLength(1); j++)
                 if ((i==1)&& (j==2)) { }...
    但是當需要check的數字多的話,那就會顯得很沒有效率,不知道有沒有什麼其他方法可以方便使用的呢? 
    請高手們給我一點指點吧 我一定會虛心受教的 ~"~

    • 已編輯 Ivy_coder 2011年11月30日 上午 05:51
    2011年11月29日 上午 09:30

解答

  • http://stackoverflow.com/questions/1781172/generate-a-two-dimensional-array-via-linq

     

    你好~可以試試這樣用~


    http://mysftway.blogspot.com/ 熱誠熱心地幫忙大家! 希望與大家切磋技術哦~
    • 已標示為解答 Ivy_coder 2011年11月30日 上午 05:54
    2011年11月29日 下午 12:59
  • 看不太懂您的code,前面兩行是不是把for,打成if了?

    我用一個小小變形範例來說明,希望可以解決您的困擾,採用的是Enumerable.Intersect<TSource> 方法 ,請參考:http://msdn.microsoft.com/zh-tw/library/bb355408.aspx

    範例:

        class Program
        {
            static void Main(string[] args)
            {
                var element = new List<int[,]> { new int[,] { { 91, 99 } } };
    
                var target = new List<int[,]>
                {
                    new int[,]{{10,10}},
                    new int[,]{{91,90}},
                    new int[,]{{91,99}},
                    new int[,]{{91,91}},
                };
    
                var result = target.Intersect(element, new ArrayComparer());
    
                Console.WriteLine(result.Count().ToString());
                var answer = result.First<int[,]>();
    
                Console.WriteLine("anwser[0][0]:{0}", Convert.ToInt32(answer.GetValue(0, 0)).ToString());
                Console.WriteLine("anwser[0][1]:{0}", Convert.ToInt32(answer.GetValue(0, 1)).ToString());
            }
        }
    
        class ArrayComparer : IEqualityComparer<int[,]>
        {
            public bool Equals(int[,] x, int[,] y)
            {
                var zeroZero = Convert.ToInt32(x.GetValue(0, 0)) == Convert.ToInt32(y.GetValue(0, 0));
                var zeroOne = Convert.ToInt32(x.GetValue(0, 1)) == Convert.ToInt32(y.GetValue(0, 1));
    
                var result = zeroZero && zeroOne;
    
                return result;
            }
    
            public int GetHashCode(int[,] obj)
            {
                return 0;
            }
        }
    


    透過Intersect來取得交集,若count數大於0,代表element存在於target的list中。

    透過自訂IEqualityComparer<T>來決定,怎麼定義二維陣列的值相等。

    結果:


    若您的程式碼有SQL injection的問題,在修改完畢之前,我不願意給您任何解答。因為解決了您的程式問題,造成更大的系統漏洞問題,還不如讓程式壞掉。

    請參考:SQL injection簡介與解決方式

    常用資源參考:
    小弟的blog: In 91,wiki: my wiki
    • 已標示為解答 Ivy_coder 2011年11月30日 上午 05:54
    2011年11月29日 下午 03:13
  • 感覺您的方式已是簡單的方式了哦!

    Iterate Multi-Dimensional Array with Nested Foreach Statement


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/
    • 已標示為解答 Ivy_coder 2011年11月30日 上午 05:54
    2011年11月30日 上午 12:20
  • 如果想要判斷一組數字是否存在於某個二維陣列當中...

    給你幾個建議。

    首先,你必須先評估你的樣本。愈多樣本愈好。評估什麼呢?就是評估資料的出現有沒有規則可循。例如,如果所有樣本中這兩個數字的加總不會超過一個固定值(就像螢幕解析度的 x, y 值總和不會超過 1920 + 1200 之類),那麼你可以建立 0 到 3119 的一個固定的 hash table,每個 cell 以 linked list 指向所有相符的座標,而 hash 計算方法就是取 x 跟 y 的相加。

    接著,要檢查另一組座標有沒有出現在集合裡,你就先算出它的 hash,也就是把這組座標(例如 392, 683)的 x 與 y 值相加,例如 392 + 683 = 1075,檢查這個 hash table 的第 1074 個索引有沒有值。如果沒有值,就表示這個座標不在集合裡;如果有值,再去檢查對應的 linked list 中所有座標是否有 x 與 y 值都符合的座標。

    運用這種方法,你的計算迴圈可以減少到相當少的地步。

    如果你的資料不符合上述模式,但仍可找到其它有規則的樣式,你還是可以基於上述精神自行開發適合的做法。方法總是人想出來的。

    但如果你的樣本實在無法找到任何規則,或者情況無法套用以上所舉的模式(例如陣列中數值為浮點小數),那麼我還是可以再給你一個建議。那就是你可以把那個二維陣列封裝為兩或少數幾個屬性的自訂型別(.Net 中的 Point 類別是個很好的例子)。這種方法無法幫你提高效率,但可以幫助你在寫程式時稍為方便一點點。

    關於自訂型別的做法可以參考這一篇:http://www.dotblogs.com.tw/johnny/archive/2010/04/23/14763.aspx

     


    • 已標示為解答 Ivy_coder 2011年11月30日 上午 05:53
    2011年11月30日 上午 02:33

所有回覆

  • http://stackoverflow.com/questions/1781172/generate-a-two-dimensional-array-via-linq

     

    你好~可以試試這樣用~


    http://mysftway.blogspot.com/ 熱誠熱心地幫忙大家! 希望與大家切磋技術哦~
    • 已標示為解答 Ivy_coder 2011年11月30日 上午 05:54
    2011年11月29日 下午 12:59
  • 看不太懂您的code,前面兩行是不是把for,打成if了?

    我用一個小小變形範例來說明,希望可以解決您的困擾,採用的是Enumerable.Intersect<TSource> 方法 ,請參考:http://msdn.microsoft.com/zh-tw/library/bb355408.aspx

    範例:

        class Program
        {
            static void Main(string[] args)
            {
                var element = new List<int[,]> { new int[,] { { 91, 99 } } };
    
                var target = new List<int[,]>
                {
                    new int[,]{{10,10}},
                    new int[,]{{91,90}},
                    new int[,]{{91,99}},
                    new int[,]{{91,91}},
                };
    
                var result = target.Intersect(element, new ArrayComparer());
    
                Console.WriteLine(result.Count().ToString());
                var answer = result.First<int[,]>();
    
                Console.WriteLine("anwser[0][0]:{0}", Convert.ToInt32(answer.GetValue(0, 0)).ToString());
                Console.WriteLine("anwser[0][1]:{0}", Convert.ToInt32(answer.GetValue(0, 1)).ToString());
            }
        }
    
        class ArrayComparer : IEqualityComparer<int[,]>
        {
            public bool Equals(int[,] x, int[,] y)
            {
                var zeroZero = Convert.ToInt32(x.GetValue(0, 0)) == Convert.ToInt32(y.GetValue(0, 0));
                var zeroOne = Convert.ToInt32(x.GetValue(0, 1)) == Convert.ToInt32(y.GetValue(0, 1));
    
                var result = zeroZero && zeroOne;
    
                return result;
            }
    
            public int GetHashCode(int[,] obj)
            {
                return 0;
            }
        }
    


    透過Intersect來取得交集,若count數大於0,代表element存在於target的list中。

    透過自訂IEqualityComparer<T>來決定,怎麼定義二維陣列的值相等。

    結果:


    若您的程式碼有SQL injection的問題,在修改完畢之前,我不願意給您任何解答。因為解決了您的程式問題,造成更大的系統漏洞問題,還不如讓程式壞掉。

    請參考:SQL injection簡介與解決方式

    常用資源參考:
    小弟的blog: In 91,wiki: my wiki
    • 已標示為解答 Ivy_coder 2011年11月30日 上午 05:54
    2011年11月29日 下午 03:13
  • 感覺您的方式已是簡單的方式了哦!

    Iterate Multi-Dimensional Array with Nested Foreach Statement


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/
    • 已標示為解答 Ivy_coder 2011年11月30日 上午 05:54
    2011年11月30日 上午 12:20
  • 如果想要判斷一組數字是否存在於某個二維陣列當中...

    給你幾個建議。

    首先,你必須先評估你的樣本。愈多樣本愈好。評估什麼呢?就是評估資料的出現有沒有規則可循。例如,如果所有樣本中這兩個數字的加總不會超過一個固定值(就像螢幕解析度的 x, y 值總和不會超過 1920 + 1200 之類),那麼你可以建立 0 到 3119 的一個固定的 hash table,每個 cell 以 linked list 指向所有相符的座標,而 hash 計算方法就是取 x 跟 y 的相加。

    接著,要檢查另一組座標有沒有出現在集合裡,你就先算出它的 hash,也就是把這組座標(例如 392, 683)的 x 與 y 值相加,例如 392 + 683 = 1075,檢查這個 hash table 的第 1074 個索引有沒有值。如果沒有值,就表示這個座標不在集合裡;如果有值,再去檢查對應的 linked list 中所有座標是否有 x 與 y 值都符合的座標。

    運用這種方法,你的計算迴圈可以減少到相當少的地步。

    如果你的資料不符合上述模式,但仍可找到其它有規則的樣式,你還是可以基於上述精神自行開發適合的做法。方法總是人想出來的。

    但如果你的樣本實在無法找到任何規則,或者情況無法套用以上所舉的模式(例如陣列中數值為浮點小數),那麼我還是可以再給你一個建議。那就是你可以把那個二維陣列封裝為兩或少數幾個屬性的自訂型別(.Net 中的 Point 類別是個很好的例子)。這種方法無法幫你提高效率,但可以幫助你在寫程式時稍為方便一點點。

    關於自訂型別的做法可以參考這一篇:http://www.dotblogs.com.tw/johnny/archive/2010/04/23/14763.aspx

     


    • 已標示為解答 Ivy_coder 2011年11月30日 上午 05:53
    2011年11月30日 上午 02:33
  • 謝謝您 ^^" 但是我不打算用Linq,因為我只是在寫unit test code,不想太複雜 還是感謝您的回答


    請高手們給我一點指點吧 我一定會虛心受教的 ~"~
    2011年11月30日 上午 05:55
  • 謝謝您的詳細解釋 :)
    請高手們給我一點指點吧 我一定會虛心受教的 ~"~
    2011年11月30日 上午 05:56
  • Thanks, hashtable 也是我考慮的方向


    請高手們給我一點指點吧 我一定會虛心受教的 ~"~
    2011年11月30日 上午 05:58