题目描述
知识点
STL使用
实现
码前思考
- 这道题目给我的第一感觉就是使用高精度整数运算,但是我想错了!后面看看柳神的代码
代码实现
//高精度整数运算
#include "bits/stdc++.h"
using namespace std;
const int maxn = 1e3+10;
struct bign{
int d[maxn];
int len;
bign(){
fill(d,d+maxn,0);
len=0;
}
};
string input;
int its;
bign rev(bign a){
bign b;
//开始逆反
for(int i=a.len-1;i>=0;i--){
b.d[b.len] = a.d[i];
b.len++;
}
//去除前导0
while(b.len > 1 && b.d[b.len-1] == 0){
b.len--;
}
return b;
}
//打印函数
void p(bign a){
for(int i=a.len-1;i>=0;i--){
printf("%d",a.d[i]);
}
return;
}
bign sum(bign a,bign b){
bign c;
int carry = 0;
for(int i=0;i<a.len||i<b.len;i++){
int res = a.d[i]+b.d[i]+carry;
c.d[c.len] = res%10;
carry = res / 10;
c.len++;
}
//查看是否还有进位
while(carry!=0){
c.d[c.len] = carry % 10;
carry = carry / 10;
c.len++;
}
return c;
}
bool check(bign c){
for(int i=0;i<=c.len/2;i++){
if(c.d[i] != c.d[c.len-i-1]){
return false;
}
}
return true;
}
int main(){
its = 0;
cin>>input;
//将字符串变成数字
bign a;
int len = input.size();
for(int i=0;i<len;i++){
int digit = input[len-i-1]-'0';
a.d[a.len] = digit;
a.len++;
}
if(check(a)){
p(a);
printf(" is a palindromic number.");
return 0;
}
//接下来进行转化
while(its<10){
//得到逆反数组
bign b = rev(a);
//进行相加
bign c = sum(a,b);
p(a);
printf(" + ");
p(b);
printf(" = ");
p(c);
printf("\n");
if(check(c)){
p(c);
printf(" is a palindromic number.");
return 0;
}else{
a = c;
}
its++;
}
printf("Not found in 10 iterations.");
}
码后反思
- 上面的代码有几处不好的设计:
-
没有使用
string
,而是使用char[]
,其实这个题目用不上复杂的高精度整数运算,使用string
即可; -
没有使用自带的
reverse()
函数,而是自己去动手去写函数;数组可以直接用索引,容器得用begin()
和end()
; -
可以直接使用
string
的==
操作符判断字符串相等。
-
- 柳神的代码:见解而高效
#include <iostream> #include <algorithm> using namespace std; string rev(string s) { reverse(s.begin(), s.end()); return s; } string add(string s1, string s2) { string s = s1; int carry = 0; for (int i = s1.size() - 1; i >= 0; i--) { s[i] = (s1[i] - '0' + s2[i] - '0' + carry) % 10 + '0'; carry = (s1[i] - '0' + s2[i] - '0' + carry) / 10; } if (carry > 0) s = "1" + s; return s; } int main() { string s, sum; int n = 10; cin >> s; if (s == rev(s)) { cout << s << " is a palindromic number.\n"; return 0; } while (n--) { sum = add(s, rev(s)); cout << s << " + " << rev(s) << " = " << sum << endl; if (sum == rev(sum)) { cout << sum << " is a palindromic number.\n"; return 0; } s = sum; } cout << "Not found in 10 iterations.\n"; return 0; }
- 二刷之后发现自己之前的代码写错了:
是不需要去处前导0的!题目中的有出现前导0的情况!虽然能过题,只能说明PAT的测试用例不强!!!//去除前导0 while(b.len > 1 && b.d[b.len-1] == 0){ b.len--; }
二刷代码://使用高精度加法 #include <cstdio> #include <iostream> #include <algorithm> #include <string> using namespace std; const int maxn = 1e4+10; //内存开多大? struct bign{ int data[maxn]; int len; bign(){ fill(data,data+maxn,0); len=0; } }; bign str2bign(string& str){ int len = str.size(); bign a; for(int i=0;i<len;i++){ int num = str[i]-'0'; a.data[len-1-i] = num; a.len++; } return a; } bool check(bign a){ int len = a.len; for(int i=0;i<=len/2;i++){ if(a.data[i] != a.data[len-1-i]){ return false; } } return true; } bign add(bign a,bign b){ int carry = 0; bign c; for(int i=0;i<a.len||i<b.len;i++){ int res = a.data[i]+b.data[i]+carry; c.data[c.len] = res%10; c.len++; carry = res/10; } while(carry > 0){ //使用while循环! c.data[c.len] = carry%10; c.len++; carry = carry/10; } return c; } void showNum(bign a){ int len = a.len; for(int i=len-1;i>=0;i--){ printf("%d",a.data[i]); } return; } bign rev(bign a){ int len =a.len; bign b=a; reverse(b.data,b.data+len); //直接用reverse return b; } int main(){ string input; cin>>input; bign a; a = str2bign(input); bign b = rev(a); bign c = a; int t=10; while(t>0 && !check(c)){ c = add(a,b); showNum(a); printf(" + "); showNum(b); printf(" = "); showNum(c); printf("\n"); a = c; b = rev(a); t--; } if(check(c)){ showNum(c); printf(" is a palindromic number.\n"); }else{ printf("Not found in 10 iterations.\n"); } //cout<<check(a); return 0; }
- 仿照柳神写的字符串实现大数加法:
#include <iostream> #include <algorithm> using namespace std; string rev(string a){ string c = a; reverse(c.begin(),c.end()); return c; } string add(string a,string b){ int carry = 0; string c=""; for(int i=a.size()-1;i>=0;i--){ int res = a[i]-'0'+b[i]-'0'+carry; c+=(res%10)+'0'; carry=res/10; } while(carry!=0){ c+=(carry%10)+'0'; carry = carry/10; } //需要倒转c reverse(c.begin(),c.end()); return c; } int main(){ string a; cin>>a; string b=rev(a); string c; int t=10; while(t > 0 && a!=b){ string c = add(a,b); cout<<a<<" + "<<b<<" = "<<c<<endl; a = c; b = rev(a); t--; } if(a==b){ cout<<a<<" is a palindromic number."<<endl; }else{ cout<<"Not found in 10 iterations."<<endl; } }