0

正如Project Euler的问题 37中所述:

数字 3797 有一个有趣的特性。作为素数本身,可以从左到右连续删除数字,并在每个阶段保持素数:3797、797、97 和 7。类似地,我们可以从右到左工作:3797、379、37 和 3。

我已经解决了这个问题(答案以 7 结尾:-),但仍有一个疑问:在不使用字符串的情况下,左/右截断数字的效率如何?我构建了以下代码,但看起来很难看:

public static void Main()
{
    Console.WriteLine( // 3797, 379, 37, 3, 797, 97, 7
        String.Join(", ", 3797L.Truncate().ToArray()));
    Console.ReadLine();
}

static IEnumerable<long> Truncate(this long number)
{
    yield return number;

    long aux = number;
    while ((aux /= 10) > 0) // right to left
        yield return aux;

    // god forgive me, but it works
    while ((number = (number.Reverse() / 10).Reverse()) > 0) // left to right
    {
        yield return number;
    }
}

public static long Reverse(this long number)
{
    long reverse = number % 10;
    number = number / 10;
    while (number != 0)
    {
        reverse = (number % 10) + (10 * reverse);
        number = number / 10;
    }
    return reverse;
}

编辑:我以这段代码结束:

static IEnumerable<long> Truncate(this long number)
{
    yield return number;

    int i = 10;
    while (number / i > 0)
    {
        yield return number / i;
        yield return number % i;
        i *= 10;
    }
}
4

3 回答 3

11

要截断最右边的数字,请除以 10(您的代码已经这样做了)。

要截断 n 位数字左侧的一位数字,请将该数字取模 10^(n-1)。

示例:3797 % 1000 -> 797

编辑:澄清我建议如何获得模的值:

w <- n
d <- 1
while (w <> 0)
  test primality of w
  w <- w / 10
  d <- d * 10
end
w <- n
while (d <> 10)
  d <- d / 10
  w <- w % d
  test primality of w
end
于 2009-11-25T20:50:21.713 回答
2

你不能除以十吗?

3797/10 = 379

379/10= 37

37/10=3

不需要字符串。

要走另一条路,请使用 %

于 2009-11-25T20:50:58.167 回答
1
var numbers = GetNumbers(3797);  

public static IEnumerable<int> GetNumbers(int val)
        {
            int ba = 1;
            int result = 1;

            while(result > 0)
            {

                ba *= 10;
                result = val / ba;
                if(result > 0)
                    yield return result;
            }

        }

会产生

379 37 3

于 2009-11-25T21:01:15.480 回答