高精度之大数除法

大数除法说的比较少或许不像加法减法那样简单,或许是用的不太多。到底怎么我也不知道。

反正你会了加法减法,乘法而不会除法,就像是,打开电脑而不玩游戏,心里难受。

我是从看到了大神博客后学习了一下。

http://blog.csdn.net/hitwhylz/article/details/9700935

博客中讲的很详细

让人一看就懂,我很佩服这位同学。果断的关注了。

毕竟别人写的是别人的。

自己写的才是自己的 。于是我就捋了捋,模仿这写了一遍;

思想就是:用减法来代替除法,但是一次一次的减太慢,我们就先见10的n次方次,n可不是乱来的 因为除数不能大于被除数 就以此来决定n的大小。

照着我下面的步骤先自己写一下试一试。

1我们来输入两个数,确定位数。判断大小关系;

2然后进行把输入的被除数除数进行倒置。因为做减法嘛,比如123-23 我们要先用3来减3 所以将数倒置把3放到0的位置我们就能从0开始逐个往后处理了。

3要处理的就是我们首先减多少。比如12345 - 2 因为我们先减10的n次方 我们在这决定先减20 还是200 还是2000

决定权在两个数位数相差多少。

4 下面我们要来做减法了 比如先减20000 下一次不能减20000了 ,我们就来减2000 这一次来处理。

并且来记录相减的次数 注意减20000 的时候减一次,和2000的时候减一次,这是相差10次的。

5 最后就是尾部的处理前导0 的问题了。

下满贴上代码:

#include<iostream>
using namespace std;
//基础操作大数除法
int substract(char *a,char*b,int alen,int blen)
{
	if(alen<blen)
		return -1;
	if(alen==blen)
	{
		for(int i=alen-1;i>=0;i--)
		{
			if(a[i]<b[i]) return -1;
			if(a[i]>b[i] )break;
		}
	}
	for(int i=0;i<alen;i++)
	{
		a[i]=a[i]-b[i];
		if(a[i]<0)
		{
			a[i]+=10;
			a[i+1]--;
		}
	}
	for(int i = alen-1;i>=0;i--)
	{
		if(a[i])
			return i+1;
	}
	return 0;
}

int main()
{
	int cases;
	cin>>cases;
	while(cases--)
	{
		char _a[100];
		char _b[100];
		int _c[100];
		memset(_c,0,sizeof(_c));
		cin>>_a>>_b;
		int alen = strlen(_a);
		int blen =strlen(_b);
		if(blen>alen)
		{
			cout<<0<<endl;
			continue;
		}
		if(alen%2)
		{
			for(int i=0;i<=alen/2;i++)
			{
				int t = _a[i]-‘0‘;
				_a[i]=_a[alen-1-i]-‘0‘;
				_a[alen-1-i]=t;
			}
		}
		else
		{
			for(int i=0;i<alen/2;i++)
			{
				int t = _a[i]-‘0‘;
				_a[i]=_a[alen-1-i]-‘0‘;
				_a[alen-1-i]=t;
			}
		}
		if(blen%2)
		{
			for(int i=0;i<=blen/2;i++)
			{
				int t=_b[i]-‘0‘;
				_b[i]=_b[blen-1-i]-‘0‘;
				_b[blen-1-i]=t;
			}
		}
		else
		{
			for(int i=0;i<blen/2;i++)
			{
				int t=_b[i]-‘0‘;
				_b[i]=_b[blen-1-i]-‘0‘;
				_b[blen-1-i]=t;
			}
		}
		int a_b = alen-blen;
		for(int i=alen-1;i>=0;i--)
		{
			if(i>=a_b)
				_b[i]=_b[i-a_b];
			else
				_b[i]=0;
		}
		blen=alen;
		int temp;
		for(int i = 0 ; i<=a_b;i++)
		{
			while((temp = substract(_a,_b+i,alen,blen-i))>=0)
			{
				alen = temp;
				_c[a_b-i]++;
			}
		}
		int i=a_b;
		while(!_c[i]&&i>=0)
			i--;
		if(i>=0)
			for(i;i>=0;i--)
				cout<<_c[i];
		else
			cout<<0<<endl;
		cout<<endl;
	}
	return 0;
}

我的代码中没有注释 因为原作者中的代码注释很详细很仔细,大家可以去参考一下。

好了!

感谢自己坚持。

高精度之大数除法

时间: 2024-07-30 21:36:44

高精度之大数除法的相关文章

2014年百度之星程序设计大赛 - 初赛(第一轮) hdu Grids (卡特兰数 大数除法取余 扩展gcd)

题目链接 分析:打表以后就能发现时卡特兰数, 但是有除法取余. f[i] = f[i-1]*(4*i - 2)/(i+1); 看了一下网上的题解,照着题解写了下面的代码,不过还是不明白,为什么用扩展gcd, 不是用逆元吗.. 网上还有别人的解释,没看懂,贴一下: (a / b) % m = ( a % (m*b)) / b 笔者注:鉴于ACM题目特别喜欢M=1000000007,为质数: 当gcd(b,m) = 1, 有性质: (a/b)%m = (a*b^-1)%m, 其中b^-1是b模m的逆

高精度之大数乘小数

今天下载百度文库资料时发现了 发现了内蒙古电子信息学院的ACM模板. 打开看了一下刚开始就是高精度的计算问题. 于是我就写了写.说实话在我的心里对这些东西有点抵触.因为接触的时候没能很好的掌握所以以后遇到这样的问题总是逃避,虽然逼着自己也能写出来,但是就是不愿意去写. 今天看到一个人的博客让我受益很深.其实不是内容,当然内容也很好.让我感觉到,其实厉害的人不是有多大的成就,会多少别人听都没听过的知识,把一件小事情做好,做的自己满意这就是成功. 闲话不扯了,我们来说一下高精度乘法问题. 大数乘小数

组合数学 + 大数乘法 + 大数除法 之 hdu 1261 字串数

//  [3/17/2015 JmingS] /* 此题可直接推导出公式: {(A1+A2+……+An)!} / {A1!A2!……An!} 由于 (12×26)! = 312! 只能通过数组来存储,所以又涉及『大数乘法』和『大数除法』, 大数实现的主要思想模拟手算,具体参考程序. */ 1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5

51 Nod 1029 大数除法【Java大数乱搞】

1029 大数除法 基准时间限制:4 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 给出2个大整数A,B,计算A / B和A Mod B的结果. Input 第1行:大数A 第2行:大数B (A,B的长度 <= 100000,A,B >= 0) Output 第1行:A / B 第2行:A Mod B (A % B) Input示例 987654321 1234 Output示例 800368 209 题目链接:http://www.51nod.com/onlineJud

二进制转换 ——大数除法

1132: 数据结构习题--使用栈实现进制转换 时间限制: 1 Sec  内存限制: 128 MB 提交: 15  解决: 9 [提交][状态][讨论版] 题目描述 使用栈将一个很长(>30)的十进制数转换为二进制数 输入 若干个很长的十进制数 每行一个 输出 转换为二进制,每行输出一个 样例输入 123456789012345678901234567890 753951684269875454652589568545854758545824 样例输出 110001110111010010000

3118 高精度练习之除法

3118 高精度练习之除法 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 给出两个正整数A和B,计算A/B整数部分的值.保证A和B的位数不超过500位. 输入描述 Input Description 读入两个用空格隔开的正整数 输出描述 Output Description 输出A/B整数部分的值 样例输入 Sample Input 15 4 样例输出 Sample Output 3 数据范围及提示 

关于大数除法

最近在九度oj上看了几个关于大数的问题,特意在这里总结一番. 要知道我们要将一个1000多位的十进制数转换为二进制数,是没有哪个类型能装得下的,所以在这里我们的手动模拟辗转相除法.实现将一个很长的十进制数字符串转换成二进制的字符数组. 首先我们来看看这些int,long等等的取值范围,明白它们到底可以存多大,我们才能放心到底什么时候可以用,什么时候不可以用. 数据类型名称 字节数 别名 取值范围 int * signed,signed int 由操作系统决定,即与操作系统的"字长"有关 unsi

高精度之大数乘大数

上一篇说了简单的大数乘以小数的问题,绝大多数的问题解决不了. 现在我们来说一下大数乘以大数. 大数乘以大数也是用来模拟手算. 举个例子吧! 先从个位开始一个一个的乘 乘完个位然后再乘十位,乘十位的时候要和个位的想成的结果相加. 这里注意乘十位的时候 就不要和乘个位数字的结果中的最后一位相加了 .就是如图搓位. 就是这样 . 下面先贴上我的代码. #include<iostream> #include<string.h> using namespace std; void mult(

大数除法(lld最多19位)

大数除法的核心:把除法运算转化为减法运算,根据除法运算的特点, 有两个大整数a和b,当a==b时,a/b==1,余数是0.(a!=0,b!=0) 当a>b时,a/b>=1,余数需要通过计算求得. 当a<b时,a/b=0,余数就是a. 以7546除23为例. 先减去23的100倍,就是2300,可以减3次,余下646.   此时商就是300: 然后646减去23的10倍,就是230,可以减2次,余下186.此时商就是320: 然后186减去23,可以减8次,此时商就是328. 特例 本题要