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

发布于 2024-08-12 09:36:12 字数 1486 浏览 4 评论 0原文

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

As stated in problem 37 at Project Euler:

The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.

I already solved this problem (answer ends with 7 :-), but a doubt remains: how efficiently left/right truncate a number, WITHOUT using strings? I built following code, but it seems ugly:

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

EDIT: I ended with this code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

长梦不多时 2024-08-19 09:36:12

要截断最右边的数字,请除以 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

To truncate the rightmost digit, divide by 10 (your code already does that).

To truncate one digit on the left of a n-digit number, take the modulo of the number by 10^(n-1).

Example: 3797 % 1000 -> 797

EDIT: to clarify how I suggest to get the value for the modulo:

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
‘画卷フ 2024-08-19 09:36:12

不能除以十吗?

3797/10 = 379

379/10= 37

37/10=3

无需字符串。

要走另一条路,请使用 %

Could you not divide by tens?

3797/10 = 379

379/10= 37

37/10=3

No strings needed.

To go the other way use %

谜兔 2024-08-19 09:36:12
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

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

        }

will produce

379 37 3

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文