【问题标题】:Get first two digits of a long long number [closed]获取长长数字的前两位数字[关闭]
【发布时间】:2018-05-14 13:17:28
【问题描述】:

您好,我有一个long long 号码,长度为 13,15 和 16 位。我想得到这些数字的前两位(从左边开始)。 例如:

Enter Number = 1234567890123;
First 2 digits = 12
Enter Number = 453456789012345;
First 2 digits = 45
Enter Number = 3534567890123456;
First 2 digits = 35

【问题讨论】:

  • 那么到目前为止,您尝试过什么?就 C 实现而言,您不了解问题的哪一部分?你熟悉 C 算术运算符吗?如果没有,您应该查看 C 文档。
  • 作为一种快速且非常肮脏的技巧,您可以将数字转换为字符串,使用长度为 2 的子字符串,然后将该字符串解析回数字。
  • 特别是如果该数字在编译时可用,那么它不再是一个肮脏的黑客而是正确的解决方案。这看起来像一个运行时变量,然后接受的答案很好,但我发布了一个编译时版本仅供参考。
  • 数字转字符串,反转字符串,转回整数,取% 100,再转字符串,再反转。如有必要,最后再次转换为整数。 :-)

标签: c long-long


【解决方案1】:

反复除以 10 直到达到 0,记住该数字的倒数第二个值,您最终将作为结果返回。

换句话说,

#include <stdio.h>

int main(void) {
    long long n = 3534567890123456; 
    long long n1 = n, n2 = n; // n2 will hold the first two digits. 
    while (n){
        n2 = n1;
        n1 = n;
        n /= 10;
    }   
    printf("%lld", n2); 
}

我将n1n2 初始化为n,因此如果n 的大小小于100,则返回正确的结果。

请注意,此算法粗心地考虑了一个不必要的步骤(您无需运行n 一直到0),但这样做可以避免担心n 的负面情况,并且n1 也会产生第一个数字,这可能很有用。

【讨论】:

  • 谢谢!像魅力一样工作。
  • @DynamicQ:给出这样的解决方案有点淘气,所以请确保你了解这里发生了什么。
  • 如果我只需要第一个数字我会怎么做?
  • @DynamicQ n1 最终成为第一位。
  • @DynamicQ:如果您知道这些数字通常超过 13 位,您可以通过在 while 循环之前执行 if (n &gt; 1e11L) n /= 1e11L; 来节省几个 CPU 时钟。或者,摆脱数字的更通用方法(不使用log)是二进制搜索“最佳”小数位数。当然,这与简单的家庭作业无关。
【解决方案2】:

假设该数字在编译时可用,您可以在编译时通过将其转换为字符串来提取它:

#include <stdio.h>

#define NUMBER 1234567890123

#define STR(n) #n
#define FIRST(n)  STR(n)[0]
#define SECOND(n) STR(n)[1]

int main(void)
{
  printf("%c %c", FIRST(NUMBER), SECOND(NUMBER));

  return 0;
}

【讨论】:

    【解决方案3】:

    如果您不需要考虑负数,@Bathsheba 算法的稍微简单的版本将是:

    #include <stdio.h>
    
    int main(void)
    {
        long long n = 3534567890123456;
    
        // divide until we get to 10..99
        while (n >= 100)
            n /= 10;
    
        printf("%lld", n);
        return 0;
    }
    

    如果你也知道数字大于13位,可以用1e11除(1e11是浮点字面量,见下面的cmets)100000000000开头, 以减少循环内的迭代次数。你也可以反转负数,如果这些是可能的输入:

    #include <stdio.h>
    
    int main(void)
    {
        long long n = 3534567890123456;
    
        // handle negative numbers
        if (n < 0)
            n = -n; 
    
        // get rid of 11 digits
        if (n >= 100000000000)
            n /= 100000000000;
    
        // handle the remaining digits 
        while (n >= 100)
            n /= 10;
    
        printf("%lld", n);
        return 0;
    }
    

    【讨论】:

    • 最好除以整数100000000000,以减少浮点错误的可能性(同时也提高性能)。
    • 大,大哎呀。 1e11 是一个 double 常量,它会导致另一个参数的类型转换!否则,这种方法是一种很好的方法。
    • @Bathsheba:感谢您的提示,除以双精度是一个非常糟糕的主意,肯定会有它会给出错误结果的情况,我有一个非常错误的想法 1e11 会是在这种情况下,a 被编译器视为 long long 文字。
    • 这对于讨厌的极端情况确实有问题:long long n = LLONG_MIN; 该值虽然不太可能是“13,15 和 16”位的长度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多