我想问一下如何重新排序Int32
中的数字,这样就可以得到最大的数字。
这是一个可视化我想要做的事情的例子:
2927466 -> 9766422
12492771 -> 97742211
我想在不使用System.Linq
命名空间的情况下执行数字的排序,而不将整数转换为字符串值。
这是我到目前为止所得到的:
public static int ReorderInt32Digits(int v)
{
int n = Math.Abs(v);
int l = ((int)Math.Log10(n > 0 ? n : 1)) + 1;
int[] d = new int[l];
for (int i = 0; i < l; i++)
{
d[(l - i) - 1] = n % 10;
n /= 10;
}
if (v < 0)
d[0] *= -1;
Array.Sort(d);
Array.Reverse(d);
int h = 0;
for (int i = 0; i < d.Length; i++)
{
int index = d.Length - i - 1;
h += ((int)Math.Pow(10, index)) * d[i];
}
return h;
}
这个算法完美无缺,但我觉得效率不高。 我想知道是否有办法更有效地做同样的事情,以及如何改进我的算法。
答案 0 :(得分:7)
您可以使用此代码:
var digit = 2927466;
String.Join("", digit.ToString().ToCharArray().OrderBy(x => x));
或
var res = String.Join("", digit.ToString().ToCharArray().OrderByDescending(x => x) );
答案 1 :(得分:2)
不是说我的回答可能会或者可能不会更“高效”,但是当我读取你的代码时,你计算了你的数字中有多少位数,这样你就可以确定你的数组有多大,然后你计算了如何将数组转换为有序整数。
在我看来,您可能希望编写自己的代码来执行排序部分而不使用内置功能,这就是我的示例所做的。另外,我添加了按升序或降序排序的功能,这也很容易添加到您的代码中。
原始算法对数字进行排序,现在它对数字进行排序,使得最终结果最大或最小,具体取决于传入的第二个参数。但是,当处理负数时,第二个参数被视为相反。< / p>
using System;
public class Program
{
public static void Main()
{
int number1 = 2927466;
int number2 = 12492771;
int number3 = -39284925;
Console.WriteLine(OrderDigits(number1, false));
Console.WriteLine(OrderDigits(number2, true));
Console.WriteLine(OrderDigits(number3, false));
}
private static int OrderDigits(int number, bool asc)
{
// Extract each digit into an array
int[] digits = new int[(int)Math.Floor(Math.Log10(Math.Abs(number)) + 1)];
for (int i = 0; i < digits.Length; i++)
{
digits[i] = number % 10;
number /= 10;
}
// Order the digits
for (int i = 0; i < digits.Length; i++)
{
for (int j = i + 1; j < digits.Length; j++)
{
if ((!asc && digits[j] > digits[i]) ||
(asc && digits[j] < digits[i]))
{
int temp = digits[i];
digits[i] = digits[j];
digits[j] = temp;
}
}
}
// Turn the array of digits back into an integer
int result = 0;
for (int i = digits.Length - 1; i >= 0; i--)
{
result += digits[i] * (int)Math.Pow(10, digits.Length - 1 - i);
}
return result;
}
}
结果:
9766422
11224779
-22345899
请参阅此处的工作示例... https://dotnetfiddle.net/RWA4XV
答案 2 :(得分:1)
public static int ReorderInt32Digits(int v)
{
var nums = Math.Abs(v).ToString().ToCharArray();
Array.Sort(nums);
bool neg = (v < 0);
if(!neg)
{
Array.Reverse(nums);
}
return int.Parse(new string(nums)) * (neg ? -1 : 1);
}
答案 3 :(得分:1)
下面的代码片段从变量v中提取数字。您可以修改它以将数字存储在数组中并排序/反向。
int v = 2345;
while (v > 0) {
int digit = v % 10;
v = v / 10;
Console.WriteLine(digit);
}
您可以使用类似的逻辑从(已排序)数字重建数字:乘以10并添加下一个数字。
答案 4 :(得分:1)
我发布了第二个答案,因为我认为我得到了最有效的算法(感谢帮助Atul):)
void Main()
{
Console.WriteLine (ReorderInt32Digits2(2927466));
Console.WriteLine (ReorderInt32Digits2(12492771));
Console.WriteLine (ReorderInt32Digits2(-1024));
}
public static int ReorderInt32Digits2(int v)
{
bool neg = (v < 0);
int mult = neg ? -1 : 1;
int result = 0;
var counts = GetDigitCounts(v);
for (int i = 0; i < 10; i++)
{
int idx = neg ? 9 - i : i;
for (int j = 0; j < counts[idx]; j++)
{
result += idx * mult;
mult *= 10;
}
}
return result;
}
// From Atul Sikaria's answer
public static int[] GetDigitCounts(int n)
{
int v = Math.Abs(n);
var result = new int[10];
while (v > 0) {
int digit = v % 10;
v = v / 10;
result[digit]++;
}
return result;
}