如何左/右截断不带字符串的数字(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;
}
}
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要截断最右边的数字,请除以 10(您的代码已经这样做了)。
要截断 n 位数字左侧的一位数字,请对该数字取 10^(n-1) 的模。
示例:3797 % 1000 →第797
章 编辑:澄清我建议如何获取模值:
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:
不能除以十吗?
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 %
将产生
will produce