当前位置:  开发笔记 > 编程语言 > 正文

项目欧拉#16 - C#2.0

如何解决《项目欧拉#16-C#2.0》经验,为你挑选了1个好方法。



1> cletus..:

一系列数字.32位无符号整数是32位二进制数.字符串"12345"是一系列5位数字.数字可以以多种方式存储:作为位,字符,数组元素等.C#中具有完全精度的最大"本机"数据类型可能是十进制类型(128位,28-29位).只需选择自己的数字存储方法,即可存储更大的数字.

至于其余的,这会给你一个线索:

2 1 = 2
2 2 = 2 1 + 2 1
2 3 = 2 2 + 2 2

例:

The sum of digits of 2^100000 is 135178
Ran in 4875 ms

The sum of digits of 2^10000 is 13561
Ran in 51 ms

The sum of digits of 2^1000 is 1366
Ran in 2 ms

SPOILER ALERT:C#中的算法和解决方案如下.

基本上,提到一个数字只不过是一个数字数组.这可以通过两种方式轻松表示:

作为一个字符串;

作为字符或数字的数组.

正如其他人所提到的,实际上建议以相反的顺序存储数字.它使计算更容易.我尝试了上述两种方法.我发现字符串和字符算法很烦人(在C/C++中它更容易;语法在C#中简直令人讨厌).

首先要注意的是,您可以使用一个数组执行此操作.您不需要在每次迭代时分配更多存储空间.如上所述,你可以通过将之前的2的幂加倍来找到2的幂.所以你可以通过加倍1千次来找到2 1000.可以使用通用算法完成加倍:

carry = 0
foreach digit in array
  sum = digit + digit + carry
  if sum > 10 then
    carry = 1
    sum -= 10
  else
    carry = 0
  end if
  digit = sum
end foreach

对于使用字符串或数组,此算法基本相同.最后你只需加上数字.一个简单的实现可能会在每次迭代时将结果添加到新数组或字符串中.馊主意.真的慢了下来.如上所述,它可以在适当的位置完成.

但阵列应该有多大?那也很容易.在数学上你可以将2 ^ a转换为10 ^ f(a)其中f(a)是一个简单的对数转换,你需要的数字是从10的幂的下一个更高的整数.为简单起见,你可以使用:

digits required = ceil(power of 2 / 3)

这是一个近似和充分的近似.

你可以真正优化的地方是使用更大的数字.32位有符号int可以存储+/- 20亿之间的数字(大约9个数字等于10亿,所以你可以使用32位int(有符号或无符号)基本上是10亿"数字".你可以工作你需要多少个int,创建那个数组,这就是运行整个算法所需的所有存储空间(130个字节),所有内容都已完成.

解决方案如下(在相当粗略的C#中):

    static void problem16a()
    {
        const int limit = 1000;
        int ints = limit / 29;
        int[] number = new int[ints + 1];
        number[0] = 2;
        for (int i = 2; i <= limit; i++)
        {
            doubleNumber(number);
        }
        String text = NumberToString(number);
        Console.WriteLine(text);
        Console.WriteLine("The sum of digits of 2^" + limit + " is " + sumDigits(text));
    }

    static void doubleNumber(int[] n)
    {
        int carry = 0;
        for (int i = 0; i < n.Length; i++)
        {
            n[i] <<= 1;
            n[i] += carry;
            if (n[i] >= 1000000000)
            {
                carry = 1;
                n[i] -= 1000000000;
            }
            else
            {
                carry = 0;
            }
        }
    }

    static String NumberToString(int[] n)
    {
        int i = n.Length;
        while (i > 0 && n[--i] == 0)
            ;
        String ret = "" + n[i--];
        while (i >= 0)
        {
            ret += String.Format("{0:000000000}", n[i--]);
        }
        return ret;
    }


2 ^ 3 = 8. 2 ^ 2 = 4. 2 ^ 3如何不等于2 ^ 2 + 2 ^ 2?
谁认为这是冒犯性的是一个完整的白痴.
看到它是我无法理解的超级特殊*数学.无论是我还是假设你在增加而不是添加,尽管我在"纠正"你时甚至复制了添加符号.
推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有