如何左/右截断不带字符串的数字(Euler#37)

时间:2009-11-25 20:47:06

标签: c# truncate

正如problem 37 Project Euler所述:

  

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

3 个答案:

答案 0 :(得分:11)

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

要截断一位数字左边的一位数字,请将数字的模数乘以10 ^(n-1)。

示例:3797%1000 - &gt; 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

答案 1 :(得分:2)

你能否除以数十?

3797/10 = 379

379/10 = 37

10分之37= 3

不需要任何字符串。

反过来使用%

答案 2 :(得分: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