使用C#重新排序整数位

时间:2015-05-27 00:30:19

标签: c# sorting numbers int32

我想问一下如何重新排序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;
    }

这个算法完美无缺,但我觉得效率不高。 我想知道是否有办法更有效地做同样的事情,以及如何改进我的算法。

5 个答案:

答案 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;
}