題目給出多組資料,判斷輸入的兩個數是否超出 int 型變量的取值範圍,并判斷最終計算結果是否超出 int 取值範圍
這裡先給出我自己最初寫的AC代碼:
思路:
用兩個string來儲存輸入的數,将他們與 int 的最大值比較大小,然後求出他們的和或者是積來判斷其與int最大值的大小關系
Result : Accepted Memory : 0 KB Time : 15 ms
/*
* Author: Gatevin
* Created Time: 2014/7/3 16:54:43
* File Name: test.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;
string s1,s2,ans;
bool check(string s)//判斷其與int最大值的關系
{
bool zero = true;
for(int i = 0; i < s.length(); i++)//找到s的起始位,以為之前加法和乘法運算有将s反向過,現在反向回來會有前導零
{
if(s[i] != '0')
{
zero = false;
break;
}
}
if(zero) return false;//如果zero = 0,則說明 s = "0"
int flags = 0;
for(int i = 0; i < s.length(); i++)
{
if(s[i] != '0')
{
flags = i;
break;
}
}
int lens = s.length() - flags;
string tmp;
if(sizeof(int)*8 == 32)
{
tmp = "2147483647";
}
else
{
tmp = "32767";
}
int lenm = tmp.length();
if(lens > lenm)
{
return true;
}
if(lens < lenm)
{
return false;
}
for(int i = flags, j = 0; i <= s.length() - 1 && j <= tmp.length() - 1; i++,j++)
{
if(s[i] > tmp[j])
{
return true;
}
if(s[i] < tmp[j])
{
return false;
}
}
return false;
}
void judge(string ss1, string ss2, char op)
{
bool res;
if(op == '*')
{
string ans(ss1.length() + ss2.length() + 1, '0');//乘法運算
reverse(ss1.begin(), ss1.end());
reverse(ss2.begin(), ss2.end());
int c;
for(int i = 0; i < ss1.length(); i++)
{
c = 0;
for(int j = 0; j < ss2.length(); j++)
{
/*
* 理由參照 剛寫的 UVA 10106 的題解
*/
int tmp1 = ((ans[i + j] - '0') + c + (ss1[i] - '0')*(ss2[j] - '0')) /10;
int tmp2 = ((ans[i + j] - '0') + c + (ss1[i] - '0')*(ss2[j] - '0')) % 10;
ans[i + j] = tmp2 + '0';
c = tmp1;
}
ans[i + ss2.length()] += c;
}
reverse(ans.begin(), ans.end());
res = check(ans);
}
else
{
string ans(max(ss1.length(), ss2.length()) + 1,'0');
reverse(ss1.begin(), ss1.end());
reverse(ss2.begin(), ss2.end());
int c = 0;
if(ss1.length() >= ss2.length())//模拟加法
{
for(int i = 0; i < ss2.length(); i++)
{
ans[i] = (ss1[i] - '0' + ss2[i] - '0' + c) % 10 + '0';
c = (ss1[i] - '0' + ss2[i] - '0' + c) / 10;
}
for(int j = ss2.length(); j < ss1.length(); j++)
{
ans[j] = (ss1[j] - '0' + c) % 10 + '0';
c = (ss1[j] - '0' + c) /10;
}
ans[ss1.length()] += c;//小心最後的進位
}
else
{
for(int i = 0; i < ss1.length(); i++)
{
ans[i] = (ss2[i] - '0' + ss1[i] - '0' + c) % 10 + '0';
c = (ss2[i] - '0' + ss1[i] - '0' + c) / 10;
}
for(int j = ss1.length(); j < ss2.length(); j++)
{
ans[j] = (ss2[j] - '0' + c) % 10 + '0';
c = (ss2[j] - '0' + c) /10;
}
ans[ss2.length()] += c;
}
reverse(ans.begin(), ans.end());
res = check(ans);
}
if(res)
{
cout<<"result too big"<<endl;
}
}
int main()
{
char mid;
while(cin>>s1>>mid>>s2)
{
bool c1 = check(s1);
bool c2 = check(s2);
cout<<s1<<" "<<mid<<" "<<s2<<endl;
if(c1)
{
cout<<"first number too big"<<endl;
}
if(c2)
{
cout<<"second number too big"<<endl;
}
judge(s1,s2,mid);
}
return 0;
}
然後是套用模闆寫的代碼:
Result : Accepted Memory : 0 KB Time : 15 ms
/*
* Author: Gatevin
* Created Time: 2014/7/4 12:58:26
* File Name: test.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;
struct bign
{
int len,s[1000];
bign()
{
len = 0;
memset(s, 0 ,sizeof(s));
}
bign operator = (const char* num)
{
len = strlen(num);
for(int i = 0; i < len; i++)
{
s[i] = num[len - i - 1] - '0';
}
return *this;
}
bign operator = (int num)
{
char s[1000];
sprintf(s, "%d", num);
*this = s;
return *this;
}
bign(int num)
{
*this = num;
}
bign(const char* num)
{
*this = num;
}
string str() const
{
string res = "";
for(int i = 0; i < len; i++)
{
res = (char)(s[i] + '0') + res;
}
if(res == "")
{
res = "0";
}
return res;
}
bign operator + (const bign& b) const
{
bign c;
c.len = 0;
for(int i = 0, g = 0; g || i < max(len, b.len); i++)
{
int x = g;
if(i < len) x += s[i];
if(i < b.len) x += b.s[i];
c.s[c.len++] = x % 10;
g = x / 10;
}
return c;
}
bign operator * (const bign& b) const
{
bign c;
c.len = len + b.len;
int k;
for(int i = 0; i < len; i++)
{
k = 0;
for(int j = 0; j < b.len; j++)
{
int tmp1 = (s[i] * b.s[j] + k + c.s[i + j]) / 10;
int tmp2 = (s[i] * b.s[j] + k + c.s[i + j]) % 10;
c.s[i + j] = tmp2;
k = tmp1;
}
c.s[i + b.len] += k;
}
while(c.len > 1)
{
if(c.s[c.len - 1] == 0)
{
c.len--;
}
else
{
break;
}
}
return c;
}
bign operator += (const bign& b)
{
*this = *this + b;
return *this;
}
bool operator < (const bign& b) const
{
if(len != b.len) return len < b.len;
for(int i = len - 1; i >= 0; i--)
{
if(s[i] != b.s[i])
{
return s[i] < b.s[i];
}
}
return false;
}
};
istream& operator >> (istream &in, bign & x)
{
string s;
in >> s;
x = s.c_str();
return in;
}
ostream& operator << (ostream & out, const bign& x)
{
out << x.str();
return out;
}
int main()
{
bign x1,x2;
char op;
bign max_int = (1 << (sizeof(int)*8 - 1)) - 1;
while(cin>>x1>>op>>x2)
{
cout<<x1<<" "<<op<<" "<<x2<<endl;
while(x1.len > 1)//處理資料輸入可能是有前導零的情況
{
if(x1.s[x1.len - 1] == 0)
{
x1.len--;
}
else
{
break;
}
}
while(x2.len > 1)
{
if(x2.s[x2.len - 1] == 0)
{
x2.len--;
}
else
{
break;
}
}
if(max_int < x1)
{
cout<<"first number too big"<<endl;
}
if(max_int < x2)
{
cout<<"second number too big"<<endl;
}
if(op == '+')
{
if(max_int < x1 + x2)
{
cout<<"result too big"<<endl;
}
}
if(op == '*')
{
if(max_int < x1*x2)
{
cout<<"result too big"<<endl;
}
}
}
return 0;
}