浅谈进制思想:
日常生活中我们习惯用十进制去运算;
为了方便电脑识别开发出了二进制,又因为2^3=8 , 2^4=16,因此应运而生了八进制与16进制。
世上本没有路,走的人多了,也便成了路,那么既然二进制可以衍生出8,16进制,为什么十进制不可以呢。
因此聪明的人们开发出了万进制,也就是10^4=10000 模仿二进制与十六进制的运算。渐渐的,我们发现万进制在进行大数运算方面有着无可比拟的优势。
如:662343889 * 5 = 3311719445
那么如果用万进制计算:可以设一个数组a[3]; a[2] = 3889 ; a[1] = 6234 ; a[0] = 6 ;
第一步:a[2] * 5 = 19445 ; 19445 %10000 = 1余9445 9445留下,1进位;
第二步:a[1] * 5 = 31170 ; 31170 %10000 = 3余1170 1170留下,加上进位的1为1171(终值),3进位;
第三步:a[0] * 5 = 30 ; 30+3(进位)为终值。
按顺序输出得:3311719945 ;仅仅三步我们便得出了最后结果,如果用十进制呢?每位相加,对于本例,至少要十步吧。效率快了3倍不止。
注意点:
本题 严格 模拟手算。(见11行-19行代码)
1、本题用万能头文件代替#include<iostream>
和#include<iomanip>
。
传送门→万能头文件
2、万进制逢万进一,效率极高,日后做ACM也是非常优秀的代码。
3、用cin输入char型数组,a[strlen(a)]的值为空, 一定要补0!见第九行代码。(笔者被坑的很惨)
4、最后输出时,第一要过滤值为0的数,第二要过滤第一个值不为0的数。(见21-28行代码)
如:0000 0123 2345 。 这个数的0000不能输出。且0123要变为123
5、26行的作用是:让形如:1234 567 2345 的数,变为:1234 0567 2345
代码:
#include<bits/stdc++.h>
using namespace std;
int main() {
char a1[100], a2[100]; memset(a1,'0',sizeof(a1)); memset(a2,'0',sizeof(a2));
int b1[25]; memset(b1, 0, sizeof(b1)); //int型长度是char型的四分之一
cin >> a1 >> a2;
reverse(a1,a1+strlen(a1)); reverse(a2,a2+strlen(a2)); //这里要反转两次
reverse(a1,a1+100); reverse(a2,a2+100);
a1[strlen(a1)] = '0'; a2[strlen(a2)] = '0'; //这里需要置0,否则是空。
int places = 0, carry;
for(int i = 99; i >= 0; i -= 4) {
carry = 0;
b1[places] += ((a1[i-3]-'0')*1000+(a1[i-2]-'0')*100+(a1[i-1]-'0')*10+(a1[i]-'0')+
(a2[i-3]-'0')*1000+(a2[i-2]-'0')*100+(a2[i-1]-'0')*10+(a2[i]-'0'));
carry = b1[places]/10000;
b1[places]%=10000;
places++; //下一位
if(carry > 0) b1[places]++; //进位
}
bool flag1 = false, flag2 = false;
for(int i = places; i >= 0; i--) {
if(!flag1 && b1[i] == 0) continue; //忽略前导0
else {
flag1 = !flag1;
if(!flag2) { flag2 = !flag2; cout << b1[i]; }
else cout << setw(4) << setfill('0') << b1[i]; //填充0
}
}
return 0;
}