C语言实现:
最基本的一个运算,可以用数组或指针做
一.加法
1.自己的代码,真是一点都不简洁,水平有限啊!
#include<stdio.h>
#include<string.h>
int max(int len1, int len2)
{
return len1 > len2 ? len1 : len2;
}
int main()
{
char s1[100], s2[100],s3[100];
int s[500];
int len1, len2;
scanf("%s%s", s1,s2);
len1 = strlen(s1);
len2 = strlen(s2);
if (len1 >= len2)
{//s2在复制时会变动,导致后面的数赋值为前面已经赋值过的值,所以
memcpy(s3, s2, sizeof(s2));//引入s3数组保留前面的值
for (int i = 0; i < len2; i++)
{
s2[i + len1 - len2] = s3[i];
}
for (int i = 0; i < len1 - len2; i++)
s2[i] = '0';
}
if (len1 < len2)
{
memcpy(s3, s1, sizeof(s1));
for (int i = 0; i < len1; i++)
{
s1[i + len1 - len2] = s3[i];
}
for (int i = 0; i < len2 - len1;i++)
s1[i] = '0';
}
int n = max(len1, len2) - 1;
s[n] = (s1[n] + s2[n]-96)%10;
for (int i = n-1; i >= 0; i--)
{
s[i] = (s1[i] + s2[i]-96) % 10 + (s1[i + 1] + s2[i + 1]-96) / 10;
}
for (int i = 0; i <= n; i++)
printf("%d", s[i]);
printf("\n");
return 0;
}
2.网上的代码(POJ1503)
可以计算多个相加并且简洁,膜拜
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
char s[101];
int sum[101];
int main()
{
int i, j;
while (gets(s), strcmp(s, "0")) //利用strcmp比较输入s是否为0,为0就结束,类似return 0;
{//巧妙化解开多少个数组 算多少个数的和的局面
j=strlen(s);
for (i=j-1; i>=0; --i)
{
sum[j-i-1]+=(s[i]-'0');//s[i]-'0'表示字符数字转化成int数字 倒序加到sum中 sum第一个数是s的最后一个数的和
}
}
j=101-1; //这里要-1,否则后面sum[j]数组越界
while(!sum[j]) --j; //重新赋值j 使j为目前sum的总位数
for (i=0;i<j;++i)
{ //如果sum[i]加成两位数 将十位数加给前一位数
sum[i+1]+=sum[i]/10;
sum[i]=sum[i]%10;
}
for (i=j; i>=0; --i)
{
printf("%d", sum[i]);
}
printf("\n");
return 0;
}
二.减法
1.自己写的代码
还是写的又臭又长,无奈,代码水平有限,不过应该可以改进,懒得弄了
#include<stdio.h>
#include<string.h>
char s1[100], s2[100];
int a[100] = { 0 }, b[100] = { 0 };
int sum[200] = { 0 };
//分开来讨论,都先较大数减较小数
void more(int n1, int n2)//第一个数长度大于第二个数
{
for (int i = 0; i < n1; i++)
{
if (a[i] < b[i])
{
sum[i] = 10 + a[i] - b[i];
a[i + 1]--;
}
else
sum[i] = a[i] - b[i];
}
for (int i = n1 - 1; i >= 0; i--)
printf("%d", sum[i]);
printf("\n");
}
void less(int n1, int n2)//第一个数长度小于第二个数
{
for (int i = 0; i < n2; i++)
{
if (b[i] < a[i])
{
sum[i] = 10 + b[i] - a[i];
b[i + 1]--;
}
else
sum[i] = b[i] - a[i];
}
printf("-"); //前面加一个负号
for (int i = n2 - 1; i >= 0; i--)
printf("%d", sum[i]);
printf("\n");
}
int main()
{
scanf("%s%s", s1, s2);
int n1 = strlen(s1), n2 = strlen(s2);
for (int i = 0; i < n1; i++)
a[i] = s1[n1 - i-1]-'0';
for (int i = 0; i < n2; i++)
b[i] = s2[n2 - i-1]-'0';
if (n1 > n2)
more(n1, n2);
else if (n1 < n2)
less(n1, n2);
else //长度相同就判断大小
{
int m = strcmp(s1, s2);
if (m == -1)
less(n1, n2);
else if (m == 1)
more(n1, n2);
else
printf("0\n");
}
return 0;
}
看了一下网上的代码好像也没有特别简洁的,感觉我这写的也不错了
三:乘法
要点:
1.乘法中有个规则:假如结果的下标为m
sum[m]=a[0]*b[m]+a[1]*b[m-1]+a[2]*b[m-2]……a[m]*b[0]
2.先将所有的数加到一起得到所有的sum[m],再对sum进行进位操作
即跟上面大数的加法的大神代码思路一致
第一点我想到了,然而第二点没想到,做半天做不出,无奈,代码转换能力太差
下面的代码是在网上的代码的基础上改的,原先的有点小错误
#include<stdio.h>
#include<string.h>
int main()
{
char a[2000], b[2000];
int ans1[2000], ans2[2000], ans[4000];
int i, j;
memset(ans1, 0, sizeof(ans1));//必须先全赋值为0防止干扰
memset(ans2, 0, sizeof(ans2));
memset(ans, 0, sizeof(ans));
scanf("%s%s", a, b);
int len1 = strlen(a);
int len2 = strlen(b);
if (len1 > len2) //确保第二个数位数较小
{ //先倒序得到数字的数组
for (i = len1 - 1; i >= 0; i--)
ans1[len1 - 1 - i] = a[i]-48;
for (i = len2 - 1; i >= 0; i--)
ans2[len2 - 1 - i] = b[i]-48;
}
else //确保ans2位数比ans1小
{
for (i = len1 - 1; i >= 0; i--)
ans2[len1 - 1 - i] = a[i]-48;
for (i = len2 - 1; i >= 0; i--)
ans1[len2 - 1 - i] = b[i]-48;
}
if (len1 < len2)//确保len2是比较小的数,这样好理清思路
{
int t;
t = len2;
len2 = len1;
len1 = t;
}
for (i = 0; i < len2; i++) //这里牵涉到一些数学知识如上
for (j = 0; j < len1; j++)
{
ans[j + i] += ans1[j] * ans2[i];
if (ans[i+j] >= 10)
{
ans[i +j+ 1] += ans[i+j] / 10;
}
ans[i+j] = ans[i+j] % 10;
}
if(ans[len1+len2-1]!=0) //判断最前面的那个是否为0,为0则跳过
printf("%d",ans[len1+len2-1]);
for (i = len1+len2 - 2; i >= 0; i--)
{
printf("%d", ans[i]);
}
printf("\n");
return 0;
}
C++类实现:
学了一年了,现在可以用C++的类来实现这个问题,感觉还是有挺大进步的。
#include<iostream>
#include<cstring>
#include<cctype>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class bignumber
{
private:
static const int BASE= 1e8;
static const int WIDTH = 8;
vector<int> s;
public:
bignumber(long long num = 0) { *this = num; }
bignumber operator=(long long num)
{
s.clear();
do
{
s.push_back(num%BASE);
num /= WIDTH;
} while (num > 0);
return *this;
}
bignumber operator=(const string &str)
{
s.clear();
int x, len = (str.length() - 1) / WIDTH + 1;
for (int i = 0; i < len; i++)
{
int end = str.length() - i*WIDTH;
int start = max(0, end - WIDTH);
sscanf(str.substr(start, end - start).c_str(), "%d", &x);
s.push_back(x);
}
return *this;
}
friend ostream & operator<<(ostream &os, const bignumber &x)
{
for (int i = x.s.size() - 1; i >= 0; i--)
cout << x.s[i];
return os;
}
friend istream & operator >> (istream &is, bignumber &x)
{
string s;
if (!(is >> s))//读取失败
return is;
x = s;
return is;
}
//四则运算
bignumber operator+(const bignumber &b) const
{
bignumber c;
c.s.clear();
int last = 0;//上一次运算剩下的值,也就是进位值
for (int i = 0;; i++)
{
if (last == 0 && i >= b.s.size() && i >= s.size())
break;
int x = last;
if (i < s.size())
x += s[i];
if (i < b.s.size())
x += b.s[i];
c.s.push_back(x%BASE);
last = x / BASE;
}
return c;
}
//比较运算
bool operator<(const bignumber &b) const
{
if (s.size() != b.s.size())
return s.size() < b.s.size();
else
{
for (int i = s.size() - 1; i >= 0; i--)
if (s[i] != b.s[i])
return s[i] < b.s[i];
}
return false;//相等
}
bool operator>(const bignumber &b) const { return b < *this; }
bool operator<=(const bignumber &b) const { return !(b < *this); }
bool operator>=(const bignumber &b) const { return !(*this < b); }
bool operator!=(const bignumber &b) const { return b<*this || *this>b; }
bool operator==(const bignumber &b) const { return !(b<*this || *this>b); }
};
int main()
{
bignumber num1,num2;
while (cin >> num1 >> num2)
{
cout << num1 + num2 << endl;;
if (num1 < num2)
cout << "<" << endl;
else if(num1 > num2)
cout << ">" << endl;
else
cout << "==" << endl;
}
return 0;
}