简体   繁体   中英

Pass in a long number and return an array of all the digits and the count of each digit

For instance, if the input is set to 1234, the program will return 11213141 because digit 1 occurs once, digit 2 occurs once ... so on and so forth. Another example: 142225 => 11234151

My program works fine with small input but if the input has 10 digits or more, the result would make no sense. Please help.

class Example
{
    // Get sorted(ascending) list for each digit in num
    public static List<int> GetList(long num)
    {
        List<int> listOfInts = new List<int>();
        while (num > 0)
        {
            int remainder = (int) num % 10;
            listOfInts.Add(remainder);
            num = num / 10;
        }
        listOfInts.Sort();
        return listOfInts;
    }

    // Get minimum digit in the list
    public static int getMinimumInt(List<int> l)
    {
        int min = 10;
        foreach (int s in l)
        {
            if (s <= min)
            {
                min = s;
            }
        }
        return min;
    }

    // Get count of the minimum digit specified
    public static int getCount(int i,List<int> l)
    {
        int count = 0;
        foreach (int s in l)
        {
            if (s == i)
            {
                count++;
            }
        }
        return count;   
    }

    public static void Main()
    {
        long input =  1234567891020;  // Arbituary input

        // initialize
        List<int> outputList=new List<int>();  // List that would be eventually outputted
        List<int> listOfInt = new List<int>();

        listOfInt = GetList(input);

        //Loop end till no element left in listOfInt
        while ((listOfInt.ToArray()).Length!=0)
        {
            int item = getMinimumInt(listOfInt);
            int count = getCount(item, listOfInt);

            outputList.Add(item);             // Add the item to be counted 
            outputList.Add(count);            // Add count of the item 
            listOfInt.RemoveRange(0, count); // Remove digits that have been counted
        }

        // Output the list
        foreach (int i in outputList)
        {
            Console.Write(i);
        }
        Console.WriteLine();

        Console.ReadLine();
    }
} 

}

In your GetList() function, you are casting your 10+ digit long to an integer:

int remainder = (int) num % 10;

Attempting to place a 10+ digit number into an int means you are running up against the highest value of 32-bit integers, which is 2,147,483,647. That would explain why your results seem strange.

Use a long instead. If that isn't enough you can try System.Numerics.BigInteger , which will allow you to add more digits to it until you run out of memory.

You can use this LINQ approach, it doesn't care about numbers, just chars:

string output = String.Concat(input
    .GroupBy(c => c)
    .Select(g => String.Format("{0}{1}", g.Key, g.Count())));

If you want the result as long use long.TryParse(output, out longvariable) .

        int sourceVal = 12341231;
        string sourceStr = sourceVal.ToString();
        List<char> uniqueChars = null;
#if LINQ
        uniqueChars = sourceStr.ToCharArray().Distinct().ToList();
#else
        uniqueChars = new List<char>();
        foreach (char c in sourceStr)
            if (!uniqueChars.Contains(c))
                uniqueChars.Add(c);
#endif
        string result = "";
        foreach (var wantedChar in uniqueChars)
#if LINQ
            result += wantedChar.ToString() + (sourceStr.Count(f => f == wantedChar)).ToString();
#else
            result += wantedChar.ToString() + (sourceStr.Split(wantedChar).Length - 1).ToString();
#endif
        Console.WriteLine("Result = " + result);

This was my code to keep it as similar to yours. If you want to limit the count, use a modulus on the end (% 10) to keep the count to a single digit.

Having now seen the other Linq answer, I think that is a lot neater. Given that your maximum answer would be something like 192,939,495,969,798,999 if sorted in character order ascending, you would need a long not an int to store that.

Just change

int remainder = (int) num % 10;

to

int remainder = (int)(num % 10);

The first one is casting num to int then doing the mod 10. This will result in overflow when num is larger than int.MaxValue , typically a negative number. The second does the mod 10 first then the cast, which is safe as the mod will result in a value that can easily fit into an int .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM