2017-03-08 57 views
0

給定一組數字,按照產生最大值的方式排列它們。 示例 {54,546,548,60} 排列是6054854654給出的最大值。我想了解IComparer如何在下面的程序中工作

class IntegerConcatComparer : IComparer<int> 
{ 
    public int Compare(int x, int y) 
    { 

     var xy = int.Parse(x.ToString() + y.ToString()); 
     var yx = int.Parse(y.ToString() + x.ToString()); 
     return xy - yx; 
    } 
} 

public class Program 
{ 
    static void Main(string[] args) 
    { 
     var InputArrays = new int[] { 65, 546, 548, 54 }; 
     var Output = PossibleSequence(InputArrays); 
     Console.WriteLine("\n{0} ", Output); 

    } 


    static string PossibleSequence(int[] ints) 
    { 
     var res= ints.OrderBy(sap => sap, new IntegerConcatComparer()); 
     var reveresedOrder= res.Reverse().ToArray(); 
     return string.Join(" ", reveresedOrder); 
    } 

} 

輸出將是60 548 546 54 我需要了解我是如何排序的IComparer這陣

在此先感謝

+0

我假設你知道IComparer如何在傳統意義上工作,在這種情況下,它的邏輯是相同的,使用的方式稍有不同。如果你不知道它是如何工作的,你添加到你的問題的icomparer標記的標記wiki有一個很好的描述 – Jamiec

+0

'IComparer.Compare'不排序數組,它只是決定傳遞給它的兩個數字的女巫更大。 'IEmumerable .OrderBy'使用'IComparer'實現對序列進行排序。 – Jodrell

+1

我不知道比較器應該做什麼。它實際上做的是通過生成所有這些臨時字符串來泄漏內存。每次調用'ToString(),每個連接都會生成一個臨時字符串。如果這個數據運行在中等數量的數據和/或很長一段時間,它會導致大量昂貴的垃圾收集 –

回答

0

我寫some code that might help you understand

從本質上講,比較器可幫助您在最數字顯著訂購,你可以用我在PowComp提供的實現避免字符串操作。我懷疑可能有更高效的方式來使用一些二進制數學來做到這一點。

using System; 
using System.Collections.Generic; 

public class Program 
{ 
    public static void Main() 
    { 
     var concatComp = new ConcatComp(); 
     var modComp = new ModComp(); 
     var powComp = new PowComp(); 

     var tests = new[] 
      { 
       Tuple.Create(0, 0), 
       Tuple.Create(1, 9), 
       Tuple.Create(9, 1), 
       Tuple.Create(1, 999), 
       Tuple.Create(999, 1), 
       Tuple.Create(111, 9), 
       Tuple.Create(9, 111), 
       Tuple.Create(91, 19), 
       Tuple.Create(19, 91) 
      }; 

     foreach(var pair in tests) 
     { 
      var concatR = R(concatComp.Compare(pair.Item1, pair.Item2)); 
      var modR = R(modComp.Compare(pair.Item1, pair.Item2)); 
      var powR = R(powComp.Compare(pair.Item1, pair.Item2)); 
      Console.WriteLine(
     $"x:{pair.Item1}, y:{pair.Item2}, concatR:{concatR}, modR:{modR}, powR:{powR}"); 
     } 
    } 


    public static string R(int v) 
    { 
     if (v == 0) 
      return "="; 

     if (v < 0) 
      return "y"; 

     return "x"; 
    } 
} 

public class ConcatComp : IComparer<int> 
{ 
    public int Compare(int x, int y) 
    { 

     var xy = int.Parse(x.ToString() + y.ToString()); 
     var yx = int.Parse(y.ToString() + x.ToString()); 
     return xy - yx; 
    } 
} 

public class ModComp : IComparer<int> 
{ 
    public int Compare(int x, int y) 
    { 

     return (x % 10) - (y % 10); 
    } 
} 

public class PowComp : IComparer<int> 
{ 
    public int Compare(int x, int y) 
    { 

     return MSD(x) - MSD(y); 
    } 

    public int MSD(int v) 
    { 
     if (v < 10) 
      return v; 

     return v/(int)Math.Pow(10.0, (int)Math.Log10(v)); 
    } 
} 

代碼輸出這些結果。

x:0, y:0, concatR:=, modR:=, powR:= 
x:1, y:9, concatR:y, modR:y, powR:y 
x:9, y:1, concatR:x, modR:x, powR:x 
x:1, y:999, concatR:y, modR:y, powR:y 
x:999, y:1, concatR:x, modR:x, powR:x 
x:111, y:9, concatR:y, modR:y, powR:y 
x:9, y:111, concatR:x, modR:x, powR:x 
x:91, y:19, concatR:x, modR:y, powR:x 
x:19, y:91, concatR:y, modR:x, powR:y 
0

代碼的一點是要設法找到最大可能的數字通過串聯一個整數列表。如果打破這種邏輯下降到只有兩個數字,說前兩個([65,546])的比較器被連接起來將兩種方式,以確定哪些數字會更大,這是在問:

「比65546大或變小54665" 。

然後,它繼續爲數組中的所有其他數字組合排序,以這種方式對它們進行排序,使它們串聯在一起時,使得最大數目成爲可能。