如何使此代码更优化并运行得更快?

时间:2018-12-09 11:42:56

标签: c#

当变量c达到15时,下面的代码运行非常慢。我没有看到16以后的数据,我需要一直将其提高到25。

    public static int c = 0;
    public static void TryAll(long x, long y)
    {
        for (int i = 2; i < 10; i++)
        {
            double powered = Math.Pow(y, i);
            if (x % y == 0 && powered == x && x % 10 != 0)
            {
                c++;
                Console.WriteLine("----- {0}", c);
                Console.WriteLine(powered);
                Console.WriteLine(y);
                Console.WriteLine(i);
            }
        }
    }
    public static void Main(string[] args)
    {
        int baseNum = 0;
        for (c = c; c < 26; baseNum++)
        {

            if (baseNum > 9)
            {
                int sum = 0;
                int baseNumD = baseNum;
                while (baseNumD != 0)
                {
                    sum += baseNumD % 10;
                    baseNumD /= 10;
                }
                TryAll(baseNum, sum);
            }
        }
    }

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

这将在大约70秒内找到int.MaxValue以下的所有数字。调用Math.Pow可能会使您的性能下降,并且如果您尝试使用累加器和良好的旧乘法来找到指数,则检查多余的%是不必要的(实际上会使速度变慢): / p>

static int SumOfDigits(int n)
{
    var current = n;
    var acc = 0;

    while (current > 0)
    {
        acc += current % 10;
        current /= 10;
    }

    return acc;
}

//Current implementation only works for positive n and b
//Easy to make it work with negative values, only need to
//perform some checks in absolute values.
static bool TryFindExponent(int n, int b, out int e)
{
    e = 0;

    if (b == 0 || n == 0)
        return false;

    //Check in abs if negative inputs are expected
    if (b == 1 &&
        n != 1)
        return false;

    var acc = 1L;

    do
    {
        e += 1;
        acc *= b;
    } while (acc < n) //check in abs if negative 
                      //numbers are expected;

    if (acc == n)
        return true;

    return false;
}

static void Main(string[] args)
{
    var sw = Stopwatch.StartNew();

    for (var i = 1; i < int.MaxValue; i++)
    {
        var b = SumOfDigits(i);

        if (TryFindExponent(i, b, out var e))
        {
            Console.WriteLine($"{i} = {b}^{e}");
        }
    }

    sw.Stop();
    Console.WriteLine($"Finished in {sw.ElapsedMilliseconds/1000.0} seconds.");
}

这将在我的机器上输出:

1 = 1^1
2 = 2^1
3 = 3^1
4 = 4^1
5 = 5^1
6 = 6^1
7 = 7^1
8 = 8^1
9 = 9^1
81 = 9^2
512 = 8^3
2401 = 7^4
4913 = 17^3
5832 = 18^3
17576 = 26^3
19683 = 27^3
234256 = 22^4
390625 = 25^4
614656 = 28^4
1679616 = 36^4
17210368 = 28^5
34012224 = 18^6
52521875 = 35^5
60466176 = 36^5
205962976 = 46^5
612220032 = 18^7
Finished in 73,075 seconds.