0

Given an array of numbers, arrange them in a way that yields the largest value. Example {54,546,548,60} the arrangement is 6054854654 gives the largest value.

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);
    }

}

The output will be 60 548 546 54. I need to understand how I IComparer sorting this array

Thanks in advance

  • I assume you know how IComparer works in the traditional sense, in which case its just the same logic, used a slightly different way. If you dont know how it works, the tag wiki for the icomparer tag youve added to your question has a pretty good description – Jamiec Mar 09 '17 at 10:38
  • `IComparer.Compare` is not sorting the array, it just decides witch of the two numbers passed to it are greater. The `IComparer` implementation is used by `IEnumerable.OrderBy` to sort the sequence. – Jodrell Mar 09 '17 at 11:10
  • 1
    I don't know what that comparer is supposed to do. What it actually does, is leak memory by generating all these temporary strings. Each call to `ToString(), each concatenation, generates a temporary string. If this runs on even a moderate amount of data and/or for a long time, it will cause a lot of expensive garbage collections – Panagiotis Kanavos Mar 09 '17 at 12:05

2 Answers2

0

The point of your code is to try to find the largest possible number by concatenation a list of integers. If you break that logic down to just two numbers, say the first two ([65,546]) The comparer is concatenating them both ways to determine which number will be bigger, it is asking:

"Is 65546 bigger or smaller than 54665".

It then continues to do this for all other combinations of numbers in the array to order them in such a way that, when concatenated together, makes the largest number possible.

Jamiec
  • 133,658
  • 13
  • 134
  • 193
0

I wrote some code that might help you understand,

Essentially, the comparer helps you order by the most significant digit, you can avoid the string manipulation using the implementation I provided in PowComp. I suspect there is probably an even more efficient way to do this using some binary maths.

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));
    }
}

The code outputs these results.

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
Jodrell
  • 34,946
  • 5
  • 87
  • 124