C处理大量输入

时间:2017-04-09 14:32:16

标签: c bignum uint64

我在C ++部分已经看到很多问题。他们中的大多数人都建议使用uint64_t, unsigned long long而我已经尝试了

  • long long
  • unsigned long long
  • uint64_t中

我输入10 ^ 18作为其最大输入。 但正在处理的数字将作为一些垃圾值返回。

我将其输入为111111111111111110, 在我将其除以10^(step-1)并将其乘以10^(step-1)时的行

的价值似乎正在振荡
Right Now In 111111111111111103
Right Now In 111111111111111104 //But it should be 111111111111111100 and then -- to decreas one more

这种方法适用于较小的值。但是没有更多的投入

live demo

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<math.h>
#include<stdint.h>
#include<inttypes.h>
int step = 0;

bool isTidy(uint64_t n){
    step++;
    if(n < 10) return true;
    int lastNumber = n % 10;
    int secondLastNumber = ((n - lastNumber)/10) % 10; 
    return (lastNumber >= secondLastNumber) && isTidy((n - lastNumber)/10);
}

int main(){
    char* inputString;
    uint64_t testNumber;
    int numberOfTestcases;
    int iterator = 1;

    scanf("%d", &numberOfTestcases);
    while(numberOfTestcases --> 0){
        scanf("%"SCNu64,&testNumber);
        do{
            step = 0;
            if(isTidy(testNumber)){
                printf("Case #%d: %"PRIu64"\n",iterator++, testNumber);
                break;
            }
            printf("Right Now In %"PRIu64"\n",testNumber);
            testNumber /= pow(10,step - 1);
            testNumber *= pow(10,step - 1);

            printf("Right Now In %"PRIu64"\n",testNumber);
        }while(testNumber --> 0);
    }
    return 0;
}

编辑:试图澄清问题。并修复了扫描输入问题

2 个答案:

答案 0 :(得分:2)

第二个scanf()中的转换说明符错误。你应该:

scanf("%"SCNu64,&testNumber);

此外,其中一个printf()语句中有一个逗号:

printf("Right Now In %"PRIu64"\n",testNumber);

最好启用编译器警告来帮助捕获这些简单的错误。我总是至少编译:

gcc -Wall -Wextra -Wpedantic

如果没有启用警告,发布的代码将在没有警告的情况下编译。

大输入的附加问题可以追溯到pow()函数,该函数返回double,而不是uint64_t。一种解决方案是用对另一个返回pow()的函数的调用替换对uint64_t的调用。这是一个例子,虽然这不是长期最有效的实现:

uint64_t mypow(uint64_t base, unsigned exp)
{
    uint64_t res = 1;

    while (exp--) {
        res *= base;
    }
    return res;
}

答案 1 :(得分:1)

我不明白你使用PRIu64的原因。

我已经从Google CodeJam完成了这个问题,使用long long就可以使用简单的scanf(&#34;%lld&#34;)就足够了。

<强>编辑

  1. 由于我的回答显然不够好,这里有一些说明,因为第32行,你在打印时会得到垃圾值:

    printf("Right Now In %"PRIu64,"\n",testNumber);
    

    在PRIu64之后有一个逗号,删除它,所有值都将正确打印。如果您因其他原因(例如无限循环)而无法获得RTE。

  2. 关于代码的问题(来自Google CodeJam),它不能处理大数(和你的例子中的无限循环),因为pow()是一个双精度,大量的精度会丢失数字,if you use your own simple pow() function,您将获得AC。