• UVa 465 Overflow——WA


    上次那个大数开方的高精度的题,UVa113 Power of Cryptography,直接两个double变量,然后pow(x, 1 / n)就A过去了。

    怎么感觉UVa上高精度的题测试数据不给力啊。。。

    话说回来,我写了100+行代码,WA了,后来考虑到要忽略前导0,又WA了,实在不知道哪出问题了。

     Overflow 

    Write a program that reads an expression consisting of twonon-negative integer and an operator. Determine if either integer or the resultof the expression is too large to be represented as a ``normal'' signed integer(type integer if you areworking Pascal, type int if you areworking in C).

    Input

    An unspecified number of lines. Each line will contain an integer,one of the two operators + or *, and another integer.

    Output

    For each line of input, print the input followed by 0-3 lines containingas many of these three messages as are appropriate: ``first number too big'',``second number too big'',``result too big''.

    Sample Input

    300 + 3
    9999999999999999999999 + 11

    Sample Output

    300 + 3
    9999999999999999999999 + 11
    first number too big
    result too big

    看到好多人用atof(),就是把一个字符串转化成double型数据。

    下面是百科内容:

    表头文件 #include <stdlib.h>
    定义函数 double atof(const char *nptr);
    函数说明 atof()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('')才结束转换,并将结果返回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2。
    返回值 返回转换后的浮点型数。
    附加说明 atof()与使用strtod(nptr,(char**)NULL)结果相同。

    如果用double的话,直接将数据和2^31-1进行比较判断是否溢出就好了。

    这是别人的AC代码。

     1 //#define LOCAL
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 using namespace std;
     7 
     8 const int INT = 2147483647;
     9 const int maxn = 300;
    10 char a[maxn], b[maxn], c;
    11 
    12 int main(void)
    13 {
    14     #ifdef LOCAL
    15         freopen("465in.txt", "r", stdin);
    16     #endif
    17 
    18     double x, y, z;
    19     while(scanf("%s %c %s", a, &c, b) == 3)
    20     {
    21         printf("%s %c %s
    ", a, c, b);
    22         x = atof(a);
    23         y = atof(b);
    24         if(c == '+')
    25             z = x + y;
    26         if(c == '*')
    27             z = x * y;
    28         if(x > INT)
    29             cout << "first number too big" << endl;
    30         if(y > INT)
    31             cout << "second number too big" << endl;
    32         if(z > INT)
    33             cout << "result too big" << endl;
    34     }
    35     return 0;
    36 }
    代码君

    可我还是想把自己WA的代码贴出来,毕竟是花了大心思用心去写的。

    而且这个代码也通过了样例测试和我自己能想到的各种极端的情况。

      1 //#define LOCAL
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 using namespace std;
      6 
      7 const int maxn = 300;
      8 const char *INT = "2147483647";
      9 char a[maxn], b[maxn], c[maxn], result[maxn];
     10 int x[maxn], y[maxn], z[maxn];
     11 bool judge(char c[], int l);
     12 void fun(char c[]);
     13 
     14 int main(void)
     15 {
     16     #ifdef LOCAL
     17         freopen("465in.txt", "r", stdin);
     18     #endif
     19 
     20     char op;
     21     while(gets(c))
     22     {
     23         cout << c << endl;
     24         sscanf(c, "%s %c %s", a, &op, b);
     25         fun(a);
     26         fun(b);
     27         int la = strlen(a);
     28         int lb = strlen(b);
     29         bool flaga, flagb;
     30         if(flaga = judge(a, la))
     31             cout << "first number too big" << endl;
     32         if(flagb = judge(b, lb))
     33             cout << "second number too big" << endl;
     34 
     35         int i, j;
     36         //对结果是否溢出进行处理
     37         if(op == '+')
     38         {
     39             if(flaga || flagb)//加法运算有一个加数溢出那么结果溢出
     40             {
     41                 cout << "result too big" << endl;
     42                 continue;
     43             }
     44             memset(x, 0, sizeof(x));
     45             memset(y, 0, sizeof(y));
     46             for(i = la - 1; i >= 0; --i)
     47                 x[la - 1 - i] = a[i] - '0';
     48             for(i = lb - 1; i >= 0; --i)
     49                 y[lb - 1 - i] = b[i] - '0';
     50             for(i = 0; i < lb; ++i)//高精度加法运算
     51             {
     52                 x[i] = x[i] + y[i];
     53                 if(x[i] > 10)
     54                 {
     55                     j = i;
     56                     while(x[j] > 10)//处理连续进位的问题
     57                     {
     58                         x[j++] -= 10;
     59                         ++x[j];
     60                     }
     61                 }
     62             }
     63         }
     64 
     65         if(op == '*')
     66         {
     67             //如果乘数为0的话,那么结果不溢出
     68             if((la == 1 && a[0] == '0') || (lb == 1 && b[0] == '0'))
     69                 continue;
     70             else
     71             {
     72                 if((flaga || flagb) || (la + lb > 11))//有一个乘数溢出或者两乘数位数之和超过11位
     73                 {
     74                     cout << "result too big" << endl;
     75                     continue;
     76                 }
     77                 memset(x, 0, sizeof(x));
     78                 memset(y, 0, sizeof(y));
     79                 for(i = la - 1; i >= 0; --i)
     80                     x[la - 1 - i] = a[i] - '0';
     81                 for(i = lb - 1; i >= 0; --i)
     82                     y[lb - 1 - i] = b[i] - '0';
     83 
     84                 for(i = 0; i < lb; ++i)
     85                 {
     86                     int s = 0, c = 0;
     87                     for(j = 0; j < maxn; ++j)
     88                     {
     89                         s = x[j] * y[i] + c;
     90                         x[i + j] = s % 10;
     91                         c = s / 10;
     92                     }
     93                 }
     94             }
     95         }
     96 
     97         for(i = maxn - 1; i >= 0; --i)
     98             if(x[i] != 0)
     99                 break;
    100         memset(result, 0, sizeof(result));
    101         j = 0;
    102         for(; i >= 0; --i)
    103             result[j++] = x[i] + '0';//将结果转化为字符串好进行判断
    104         if(judge(result, strlen(result)))
    105             cout << "result too big" << endl;
    106     }
    107     return 0;
    108 }
    109 //判断一个字符串是否会溢出
    110 bool judge(char c[], int l)
    111 {
    112     if(l > 10)
    113         return true;
    114     if(l < 10)
    115         return false;
    116     if(strcmp(c, INT) > 0)
    117         return true;
    118     return false;
    119 }
    120 //忽略字符串的前导0
    121 void fun(char c[])
    122 {
    123     if(c[0] != '0')
    124         return;
    125     int i = 0, j = 0;
    126     while(c[i] == '0')
    127         ++i;
    128     for(; c[i] != ''; ++i)
    129         c[j++] = c[i];
    130     c[j] = '';
    131 }
    代码君
  • 相关阅读:
    微信小程序地图组件中的include-points怎样缩放视野并将所有坐标点在规定的视野内展示?
    两种常见的mysql集群架构
    layui+oss阿里云附件上传回调报错问题
    redis hash过期时间
    Static和Extern关键字理解
    代理模式
    中介者模式
    访问者模式
    模板方法模式
    迭代器模式
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/3817589.html
Copyright © 2020-2023  润新知