Reputation: 23
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();
}
}
}
Upvotes: 0
Views: 102
Reputation: 4808
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.
Upvotes: 3
Reputation: 460098
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)
.
Upvotes: 3
Reputation: 32266
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
.
Upvotes: 0
Reputation: 2418
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.
Upvotes: 0