none
Hashtable重複 RRS feed

  • 問題

  • 大大您們好,請問一下,我有一矩陣string[,] aa =new string[4,2]{{"1","02/03"},{"2","02/13"},{"4","02/11"},{"3","02/12"}}要對某一列矩陣做排序,我從網路上找到利用Arraylist 和Hashtable我覺得不錯的排序方式,但我發現Hashtable的鍵值是不能重複的,想請問大大,是否有何方法可以解決此問題,還是只能再另尋他法了,謝謝
    2010年4月7日 上午 09:13

解答

  • 自己實作 IComparable 介面比較快

    請參閱 MSDN 文件庫

    [IComparable 介面 ]

    Johnny大的文章

    讓 自訂類別的陣列物件具有排序與搜尋的能力


    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    • 已標示為解答 冰糖旋風 2010年4月8日 上午 03:22
    2010年4月7日 上午 09:29
    版主
  • Hi,

    稍微改一下

     

                int[,] a = new int[4, 2] { { 1, 9 }, { 2, 15 }, { 3, 9 }, { 4, 12 } };
    
                List<string> al = new List<string>();
                Hashtable ht = new Hashtable();
                for (int i = 0; i < a.GetLength(0); i++)
                {
                    ht.Add(a[i, 1].ToString ("0000") + "_" + i.ToString(), i);
                    al.Add(a[i, 1].ToString("0000") + "_" + i.ToString());
                }
                al.Sort();
    
                foreach (string key in al)
                {
                    Console.WriteLine("[" + a[(int)ht[key], 0] + "," + a[(int)ht[key], 1] + "]");
                }

     

    也可以這樣寫

     

                int[,] a = new int[4, 2] { { 1, 9 }, { 2, 15 }, { 3, 9 }, { 4, 12 } };
                List<string> a2 = new List<string>();
                for (int idx = 0; idx < a.GetLength(0); idx++)
                {
                    a2.Add(a[idx, 1].ToString("0000") + "," + a[idx, 0]);
                }
                a2.Sort();
    
                foreach (string item in a2)
                {
                    string[] values=item.Split(',');
                    Console.WriteLine(values[1] + "," + values[0].TrimStart('0'));
                }

     

    或是

     class Program
        {     
       static void Main(string[] args)
            {
                int[,] a = new int[4, 2] { { 1, 9 }, { 2, 15 }, { 3, 9 }, { 4, 12 } };
                int[] tagArray = new int[] { 0, 1, 2, 3 };
                RectangularComparer rc = new RectangularComparer(a);
                Array.Sort(tagArray, rc);
                for (int i = 0; i < tagArray.Length; i++)
                {
                    Console.WriteLine(a[tagArray[i], 1]);
                }
    }
    }
    
    class RectangularComparer : IComparer
    {
        // maintain a reference to the 2-dimensional array being sorted
        private int[,] sortArray;
    
        // constructor initializes the sortArray reference
        public RectangularComparer(int[,] theArray)
        {
            sortArray = theArray;
        }
    
        public int Compare(object x, object y)
        {
            // x and y are integer row numbers into the sortArray
            int i1 = (int)x;
            int i2 = (int)y;
    
            // compare the items in the sortArray
            return sortArray[i1, 1].CompareTo(sortArray[i2, 1]);
        }
    }
    

     


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    • 已標示為解答 冰糖旋風 2010年4月8日 上午 03:21
    2010年4月7日 上午 11:03

所有回覆

  • 自己實作 IComparable 介面比較快

    請參閱 MSDN 文件庫

    [IComparable 介面 ]

    Johnny大的文章

    讓 自訂類別的陣列物件具有排序與搜尋的能力


    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    • 已標示為解答 冰糖旋風 2010年4月8日 上午 03:22
    2010年4月7日 上午 09:29
    版主
  • Hi,

    先把您找到的排序方式或是您的Code寫出來吧

    因為換個類別也不一定能套用到您的方法中


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年4月7日 上午 09:32
  • int[,] a = new int[4, 2] { { 1, 9 }, { 2, 15 }, { 3, 9 }, { 4, 12 } };
    ArrayList al = new ArrayList();
    Hashtable ht = new Hashtable();
    for (int i = 0; i < a.GetLength(0); i++)
    {
         ht.Add(a[i, 1], a[i, 0]);
         al.Add(a[i, 1]);
    }
    al.Sort();

    大大謝謝

    2010年4月7日 上午 09:51
  • HI,

    你加到hashtable是有要做什麼嗎?

    還是你只是單純想把一樣的放一起??NameValueCollection也許是你要的。

     

    你可以參考一下這篇文章:p

    http://www.dotblogs.com.tw/alonstar/archive/2009/12/01/12239.aspx

     


    My Blog:http://www.dotblogs.com.tw/alonstar
    解決問題之後,別忘了回到論壇把正確回應標示成解答哦!
    2010年4月7日 上午 09:58
  • Hi,

    稍微改一下

     

                int[,] a = new int[4, 2] { { 1, 9 }, { 2, 15 }, { 3, 9 }, { 4, 12 } };
    
                List<string> al = new List<string>();
                Hashtable ht = new Hashtable();
                for (int i = 0; i < a.GetLength(0); i++)
                {
                    ht.Add(a[i, 1].ToString ("0000") + "_" + i.ToString(), i);
                    al.Add(a[i, 1].ToString("0000") + "_" + i.ToString());
                }
                al.Sort();
    
                foreach (string key in al)
                {
                    Console.WriteLine("[" + a[(int)ht[key], 0] + "," + a[(int)ht[key], 1] + "]");
                }

     

    也可以這樣寫

     

                int[,] a = new int[4, 2] { { 1, 9 }, { 2, 15 }, { 3, 9 }, { 4, 12 } };
                List<string> a2 = new List<string>();
                for (int idx = 0; idx < a.GetLength(0); idx++)
                {
                    a2.Add(a[idx, 1].ToString("0000") + "," + a[idx, 0]);
                }
                a2.Sort();
    
                foreach (string item in a2)
                {
                    string[] values=item.Split(',');
                    Console.WriteLine(values[1] + "," + values[0].TrimStart('0'));
                }

     

    或是

     class Program
        {     
       static void Main(string[] args)
            {
                int[,] a = new int[4, 2] { { 1, 9 }, { 2, 15 }, { 3, 9 }, { 4, 12 } };
                int[] tagArray = new int[] { 0, 1, 2, 3 };
                RectangularComparer rc = new RectangularComparer(a);
                Array.Sort(tagArray, rc);
                for (int i = 0; i < tagArray.Length; i++)
                {
                    Console.WriteLine(a[tagArray[i], 1]);
                }
    }
    }
    
    class RectangularComparer : IComparer
    {
        // maintain a reference to the 2-dimensional array being sorted
        private int[,] sortArray;
    
        // constructor initializes the sortArray reference
        public RectangularComparer(int[,] theArray)
        {
            sortArray = theArray;
        }
    
        public int Compare(object x, object y)
        {
            // x and y are integer row numbers into the sortArray
            int i1 = (int)x;
            int i2 = (int)y;
    
            // compare the items in the sortArray
            return sortArray[i1, 1].CompareTo(sortArray[i2, 1]);
        }
    }
    

     


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    • 已標示為解答 冰糖旋風 2010年4月8日 上午 03:21
    2010年4月7日 上午 11:03
  • 大大謝謝
    2010年4月8日 上午 03:21
  • Hi,

    若您會用擴充方法的話

    也可參考一下昨天我試寫的

        static class ArrayExtension
        {
            public static void Sort<T>(this T[,] array,int d2Idx)
            {            
                int count = array.GetLength(0);
                
                T[] tempArray = new T[count];                        
                for (int idx = 0; idx < count; ++idx)
                {
                    tempArray[idx] = array[idx, d2Idx];                
                }
                Array.Sort(tempArray);
    
                for (int idx = 0; idx < count; ++idx)
                {
                    T tempValue = tempArray[idx];
                    for (int idx2 = idx+1; idx2 < count; ++idx2)
                    {
                        if (array[idx2, d2Idx].Equals(tempValue))
                        {
                            array.Swap(idx, d2Idx, idx2, d2Idx);
                            int d2Idx2 = (d2Idx == 0) ? 1 : 0;
                            array.Swap(idx, d2Idx2, idx2, d2Idx2);
                        }
                    }
                }
            }
    
            public static void Swap<T>(this T[,] array, int idx1, int idx2, int targetIdx1, int targetIdx2)
            {
                T temp;
                temp = array[targetIdx1, targetIdx2];
                array[targetIdx1, targetIdx2] = array[idx1, idx2];
                array[idx1, idx2] = temp;
            }
        }

     

    使用上會變成

                int[,] a = new int[4, 2] { { 1, 9 }, { 2, 15 }, { 3, 9 }, { 4, 12 } };
                a.Sort(1);
                for (int idx = 0; idx < a.GetLength(0); ++idx)
                {
                    Console.WriteLine(a[idx, 0] + "," + a[idx, 1]);
                }

     


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年4月8日 上午 04:42
  • 大大您好,可以在請教一下問題,那你敎了我這麼多種方法,有說哪一種當資料量很大時,他耗費的cpu會較少,或者其實都相同,是看我要用哪一種方法而已,謝謝
    2010年4月8日 上午 09:53
  • Hi,

    主要還是要看您要用哪個方法

    基本上前兩個方法是拿您的去改的

    雖然可以達到目的

    但是是比較不建議的

     

    比較建議的還是使用Comparer與擴充方法的做法

    Comparer的做法比較正規

    但擴充方法使用起來比較方便

    不用重覆撰寫類似的Code

    也比較容易維護與理解

     

    CPU部分若在乎的話

    那就自行測一下摟


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年4月8日 上午 10:02
  • 大大謝謝
    2010年4月8日 上午 10:13