这道题是大数和小数之间的运算,并不是大数和大数的问题,但我总是喜欢把问题想复杂,
真是淡淡的忧伤,先贴上我自己写的调试了好久才A掉的又长又乱的代码,然后再贴上别人的
集中代码以供参考:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<ctime>
#define MAXN 10000
using namespace std;
char s[MAXN];
char ss[MAXN];
char sss[MAXN];
long long s1[MAXN];
long long s2[MAXN];
void Multi(long long n)
{
int len=strlen(s);
for(int i=0;i<len;i++)
s1[i]=s[i]-'0';
long long sum=0;
int len1=0;
for(int i=0;i<len;i++)
{
sum=sum*10+s1[i];
if(sum>=n)
{
s2[i]=sum/n;
sum=sum-sum/n*n;
}
else
{
s2[i]=0;
}
}
int i=0;
while(s2[i]==0)
i++;
for(;i<len;i++)
ss[len1++]=s2[i]+'0';
ss[len1]='\0';
}
void Pow(long long n)
{
memset(s1,0,sizeof(s1));
int len=strlen(ss);
for(int i=len-1;i>=0;i--)
{
s1[len-1-i]=ss[i]-'0';
}
int c=0;
for(int i=0;i<len;i++)
{
s1[i]=s1[i]*n+c;
c=s1[i]/10;
s1[i]%=10;
}
while(c!=0)
{
s1[len]=c%10;
c/=10;
len++;
}
for(int i=len-1;i>=0;i--)
ss[len-1-i]=s1[i]+'0';
ss[len]='\0';
}
void Sub()
{
int len=strlen(s);
int len1=strlen(ss);
for(int i=0;i<len;i++)
s1[i]=s[i]-'0';
for(int i=0;i<len1;i++)
s2[i]=ss[i]-'0';
for(int i=len-1,j=len1-1;i>=0&&j>=0;i--,j--)
{
if(s1[i]<s2[j])
{
s1[i]=10+s1[i];
s1[i-1]--;
}
s1[i]=s1[i]-s2[j];
}
for(int i=len-1;i>0;i--)
if(s1[i]<0)
{
s1[i]+=10;
s1[i-1]--;
}
int i=0;
while(s1[i]==0)
{
i++;
}
int len2=0;
for(;i<len;i++)
ss[len2++]=s1[i]+'0';
ss[len2]='\0';
}
int main()
{
long long n;
char c;
while(scanf("%s %c %lld",s,&c,&n)!=EOF)
{
memset(ss,0,sizeof(ss));
if(c=='/')
Multi(n);
else
{
Multi(n);
Pow(n);
Sub();
}
if(ss[0]=='\0')
printf("0\n");
else
puts(ss);
}
return 0;
}
先贴上最简洁的代码:
#include <cstdio>
#include <cstring>
const
int
maxsize=10000000;
char
s[maxsize],ans[maxsize];
int
main()
{
char
c;
long
long
b,a;
memset
(s,0,maxsize);
while
(
scanf
(
"%s %c %lld"
,s,&c,&b)!=EOF)
{
memset
(ans,0,maxsize);
int
i;
a=0;
int
j=0;
int
len=
strlen
(s);
for
(i=0;i<len;++i)
{
a=a*10+s[i]-
'0'
;
ans[j++]=a/b+
'0'
;
a=a%b;
}
if
(c==
'%'
)
printf
(
"%lld\n"
,a);
else
{
i=0;
while
(ans[i]==
'0'
)++i;
if
(ans[i]==0)--i;
for
(;i<=j-1;++i)
printf
(
"%c"
,ans[i]);
printf
(
"\n"
);
}
}
return
0;
}
思路: 从被除数的高位开始for(i:0 -> strlen(被除数)), 用每次用sscanf(str, "%d", &num)读入i位(要截断) num 跟除数做除法 跟 mod运算。 除的结果放入rslt[i]中, mod的结果ssprintf()回str。
- #include <cstdio>
- #include <cstring>
- using namespace std;
- #define MAX_BIT 1100
- void solve(char *str, long long second, char sign) {
- int len = strlen(str);
- char rslt[MAX_BIT];
- memset(rslt, 0, sizeof(rslt));
- for (int i = 0; i < len; i++) {
- char sTp[MAX_BIT], ch;
- memset(sTp, 0, sizeof(sTp));
- long long iTp;
- ch = str[i+1];
- str[i+1] = '\0';
- sscanf(str, "%s", sTp);
- sscanf(sTp, "%lld", &iTp);
- rslt[i] = (iTp / second) + '0';
- sprintf(str, "%*lld", i+1, iTp % second);
- str[i+1] = ch;
- }
- int i;
- if (sign != '%') {
- for (i = 0; rslt[i] == '0'; i++);
- if (rslt[i] == '\0') {
- puts("0");
- } else {
- puts(rslt + i);
- }
- } else {
- for (i = 0; str[i] == ' '; i++);
- puts(str + i);
- }
- }
- int main()
- {
- char str[MAX_BIT], sign;
- memset(str, 0, sizeof(str));
- long long second;
- while (scanf("%s %c %lld", str, &sign, &second) == 3) {
- solve(str, second, sign);
- }
- return 0;
- }
#include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 struct bign 5 { 6 int len; 7 int s[1000]; 8 }; 9 bign a,res; 10 char str[1000]; 11 long b; 12 void change(bign *a) 13 { 14 int i; 15 a->len=strlen(str); 16 for(i=0;i<a->len;i++) 17 a->s[i]=str[i]-'0'; 18 } 19 void div() 20 { 21 int i,j=0; 22 long num=0; 23 for(i=0;i<a.len;i++) 24 { 25 num=num*10+a.s[i]; 26 res.s[j]=num/b; 27 num=num%b; 28 j++; 29 } 30 (&res)->len=j; 31 } 32 long mod() 33 { 34 int i,j; 35 long ans=0; 36 for(i=0;i<a.len;i++) 37 { 38 ans=ans*10+a.s[i]; 39 ans=ans%b; 40 } 41 return ans; 42 } 43 int main() 44 { 45 char c; 46 while(scanf("%s %c %ld",str,&c,&b)!=EOF) 47 { 48 change(&a); 49 if(c=='/') 50 { 51 int i=0,j; 52 div(); 53 while(i<res.len-1&&res.s[i]==0) 54 ++i; 55 for(j=i;j<res.len;j++) 56 { 57 printf("%d",res.s[j]); 58 } 59 printf("\n"); 60 } 61 else if(c=='%') 62 { 63 long aa; 64 aa=mod(); 65 printf("%ld\n",aa); 66 } 67 } 68 return 0; 69 }最后贴一个通用的用bign类写的:
- //#define LOCAL
- #include <string.h>
- #include <stdio.h>
- #include <iostream>
- using namespace std;
- int const MAXN = 800;
- class BigNumber
- {
- public:
- int s[MAXN];
- int len;
- public:
- // 去除前导零
- void cleanLeadZero();
- // 乘以10的n次方
- void multiplyTen(int n);
- // 除以10的n次方
- void divisionTen(int n);
- // 将结果转换成字符串
- string str() const;
- // 构造函数
- BigNumber();
- BigNumber(int);
- BigNumber(const char *);
- // 截取整数的前n位数(例如1234434 调用getSub(3)的话得到的结果是123)
- BigNumber getSub(int n) const;
- // 重载赋值运算符
- BigNumber operator = (const char *);
- BigNumber operator = (int num);
- // 重载加减乘除
- BigNumber operator + (const BigNumber &) const;
- BigNumber operator - (const BigNumber &) const;
- BigNumber operator * (const BigNumber &) const;
- BigNumber operator / (const BigNumber &) const;
- BigNumber operator % (const BigNumber &) const;
- BigNumber operator -= (const BigNumber &);
- BigNumber operator += (const BigNumber &);
- BigNumber operator *= (const BigNumber &);
- BigNumber operator /= (const BigNumber &);
- // 重载比较运算符
- bool operator < (const BigNumber &) const;
- bool operator > (const BigNumber &) const;
- bool operator <= (const BigNumber &) const;
- bool operator >= (const BigNumber &) const;
- bool operator == (const BigNumber &) const;
- // 重载输入输出流
- friend istream & operator >> (istream &, BigNumber &);
- friend ostream & operator << (ostream &, BigNumber &);
- };
- void BigNumber::cleanLeadZero() {
- while (len > 1 && !s[len - 1]) len--;
- }
- void BigNumber::divisionTen(int n)
- {
- int i;
- if (n > len) {
- while (len >= 1) s[len--] = 0;
- } else {
- for (i = 0; i < len - n; i++)
- {
- s[i] = s[i + n];
- }
- len -= n;
- }
- }
- void BigNumber::multiplyTen(int n)
- {
- if (n > 0) {
- int i;
- for (i = len - 1; i >= 0; i--)
- {
- s[i + n] = s[i];
- }
- for (i = 0; i < n; i++) {
- s[i] = 0;
- }
- len += n;
- }
- }
- string BigNumber::str() const
- {
- string res = "";
- // 每个位的数逆序添加到str末尾。
- for (int i = 0; i < len; i++) {
- res = (char)(s[i] + '0') + res;
- }
- if (res == "") res = "0";
- return res;
- }
- BigNumber::BigNumber()
- {
- memset(s, 0, sizeof(s));
- len = 1;
- }
- BigNumber::BigNumber(int num) {
- *this = num;
- }
- BigNumber::BigNumber(const char * num) {
- *this = num;
- }
- BigNumber BigNumber::getSub(int n) const
- {
- BigNumber c;
- c.len = 0;
- for (int i = 0; i < n; i++) {
- c.s[c.len++] = s[len - n + i];
- }
- return c;
- }
- BigNumber BigNumber::operator = (const char * num)
- {
- len = strlen(num);
- // 整数在s数组中是逆序存放的(如:"456" 在s数组中是s[0] = 6, s[1] = 5, s[2] = 4)
- for (int i = 0; i < len; i++) {
- s[i] = num[len - i - 1] - '0';
- }
- return *this;
- }
- BigNumber BigNumber::operator = (int num) {
- char s[MAXN];
- sprintf(s, "%d", num);
- *this = s;
- return *this;
- }
- BigNumber BigNumber::operator + (const BigNumber & x) const
- {
- BigNumber r;
- r.len = 0;
- // up 是用来保持进位的
- int i, up;
- int maxLen = max(len, x.len);
- for (i = 0, up = 0; up || i < maxLen; i++) {
- int temp = up;
- if (i < len) temp += s[i];
- if (i < x.len) temp += x.s[i];
- up = temp / 10;
- r.s[r.len++] = temp % 10;
- }
- // 去除前导零
- r.cleanLeadZero();
- return r;
- }
- // 减法在使用时要注意在计算a - b时要确保a >= b;
- // 如果a < b 则计算 先输出一个'-' 再输出b - a 的结果
- BigNumber BigNumber::operator - (const BigNumber & b) const
- {
- BigNumber c;
- c.len = 0;
- int i;
- // 用来保存退位
- int down;
- for (i = 0, down = 0; i < len; i++)
- {
- int temp = s[i] - down;
- if (i < b.len) temp -= b.s[i];
- if (temp >= 0) down = 0;
- else {
- down = 1;
- temp += 10;
- }
- c.s[c.len++] = temp;
- }
- c.cleanLeadZero();
- return c;
- }
- BigNumber BigNumber::operator * (const BigNumber & b) const
- {
- int i, j;
- BigNumber c;
- c.len = len + b.len;
- for (i = 0; i < len; i++) {
- for (j = 0; j < b.len; j++) {
- c.s[i + j] += s[i] * b.s[j];
- }
- }
- for (i = 0; i < c.len - 1; i++) {
- c.s[i + 1] += c.s[i] / 10;
- c.s[i] %= 10;
- }
- c.cleanLeadZero();
- return c;
- }
- BigNumber BigNumber::operator / (const BigNumber & b) const
- {
- int i, j;
- BigNumber r;
- r.len = 0;
- // 模拟除法的过程
- // 先取blen - 1位
- BigNumber temp = this->getSub(b.len - 1);
- // 一位一位的除从而取得完整的答案
- for (i = len - b.len; i >= 0; i--)
- {
- // temp用来存储被除数的前blen位。
- temp = temp * 10 + s[i];
- // 如果temp < b则再在该位的结果为0
- if (temp < b) {
- r.s[r.len++] = 0;
- } else {
- // 否则找到第一个j使得b * j的结果大于 temp
- for (j = 1; j <= 10; j++) {
- if (b * j > temp) break;
- }
- // 因为此时(j - 1) * b小于等于temp,所有j - 1就是在该位除的结果
- r.s[r.len++] = j - 1;
- // temp 减去被减去部分为下一次迭代做准备
- temp = temp - (b * (j - 1));
- }
- }
- // 逆序(因为结果是要逆序存储的,而在求解过程中结果是顺序存储的)
- for (i = 0; i < r.len / 2; i++) {
- int temp = r.s[i];
- r.s[i] = r.s[r.len - 1 - i];
- r.s[r.len - 1 - i] = temp;
- }
- r.cleanLeadZero();
- return r;
- }
- BigNumber BigNumber::operator % (const BigNumber & b) const
- {
- BigNumber r;
- r = *this / b;
- //cout << r << endl;
- r = *this - r * b;
- return r;
- }
- BigNumber BigNumber::operator += (const BigNumber & b)
- {
- *this = *this + b;
- return *this;
- }
- BigNumber BigNumber::operator -= (const BigNumber & b)
- {
- *this = *this - b;
- return *this;
- }
- BigNumber BigNumber::operator *= (const BigNumber & b)
- {
- *this = *this * b;
- return *this;
- }
- BigNumber BigNumber::operator /= (const BigNumber & b)
- {
- *this = *this / b;
- return *this;
- }
- bool BigNumber::operator < (const BigNumber & b) const
- {
- if (len != b.len) return len < b.len;
- else {
- for (int i = len - 1; i >= 0; i--) {
- if (s[i] != b.s[i]) return s[i] < b.s[i];
- }
- }
- return false;
- }
- bool BigNumber::operator > (const BigNumber & b) const
- {
- return b < *this;
- }
- bool BigNumber::operator <= (const BigNumber & b) const
- {
- return !(b > *this);
- }
- bool BigNumber::operator >= (const BigNumber & b) const
- {
- return !(*this < b);
- }
- bool BigNumber::operator == (const BigNumber & b) const
- {
- return !(b < *this) && !(b > *this);
- }
- istream & operator >> (istream & in, BigNumber & x)
- {
- string s;
- in >> s;
- x = s.c_str();
- return in;
- }
- ostream & operator << (ostream & out, BigNumber & x)
- {
- out << x.str();
- return out;
- }
- char a[1000];
- char b[100];
- char op;
- int main()
- {
- #ifdef LOCAL
- freopen("input.txt", "r", stdin);
- //freopen("output.txt", "w", stdout);
- #endif
- while (scanf("%s %c %s", a, &op, b) != EOF) {
- BigNumber d(a);
- BigNumber k(b);
- d.cleanLeadZero();
- k.cleanLeadZero();
- if (op == '/') {
- cout << (d / k).str() << endl;
- } else {
- cout << (d % k).str() << endl;
- }
- }
- return 0;
- }