• 大数除法


    /*
       功能Function Description:     大数除法
       开发环境Environment:          DEV C++ 4.9.9.1
       技术特点Technique:
       版本Version:
       作者Author:				     可笑痴狂
       日期Date:                     20120731
       备注Notes:
       解题方法:
    	   基本的思想是反复做减法,看看从被除数里最多能减去多少个除数,商就是多少。一个一个减显然太慢,如何减得更快一些呢?
    	   以7546 除以23 为例来看一下:开始商为0。先减去23 的100 倍,就是2300,发现够减3 次,余下646。于是商的值就增加300。
    	   然后用646 减去230,发现够减2 次,余下186,于是商的值增加20。最后用186 减去23,够减8 次,因此最终商就是328。
    	   所以本题的核心是要写一个大整数的减法函数,然后反复调用该函数进行减法操作。 计算除数的10 倍、100 倍的时候,
    	   不用做乘法,直接在除数后面补0 即可。
    
    */
    #include<stdio.h>
    #include<string.h>
    #define MAX 1000
    int a1[MAX+10],a2[MAX+10],ans[MAX+10]; //a1被除数,a2除数,ans存放商。逆序存放
    char s1[MAX+10],s2[MAX+10];
    
    
    //长度为 nLen1 的大整数p1 减去长度为nLen2 的大整数p2
    //结果放在p1 里,返回值代表结果的长度
    //如不够减返回-1,正好减完返回 0
    int Substract(int *p1,int *p2,int len1,int len2)
    {
    	int i;
    	if(len1<len2)
    		return -1;
    	if(len1==len2)
    	{
    		for(i=len1-1; i>=0;--i)
    		{
    			if(p1[i]<p2[i])    //p1<p2
    				return -1;
    			else if(p1[i]>p2[i]) //p1>p2
    				break;
    		}
    	}
    	for(i=0;i<len1;++i)//要求调用本函数确保当i>=len2时,p2[i]=0
    	{
    		p1[i]-=p2[i];
    		if(p1[i]<0)
    		{
    			p1[i]+=10;
    			--p1[i+1];
    		}
    	}
    	for(i=len1-1;i>=0;--i)
    		if(p1[i])    //找到最高位第一个不为0
    			return i+1;
    	return 0;   //全部为0,说明两者相等
    }
    
    
    int main()
    {
    	int n,i,j,len1,len2,temp,nTimes;
    	scanf("%d",&n);
    	while(n--)
    	{
    		scanf("%s%s",s1,s2);
    		memset(a1,0,sizeof(a1));
    		memset(a2,0,sizeof(a2));
    		memset(ans,0,sizeof(ans));
    		len1=strlen(s1);
    		len2=strlen(s2);
    		if(len1<len2)
    		{
    			printf("0\n"); //不够除
    			continue;
    		}
    		for(i=len1-1,j=0;i>=0;--i)
    			a1[j++]=s1[i]-'0';
    		for(i=len2-1,j=0;i>=0;--i)
    			a2[j++]=s2[i]-'0';
    		nTimes=len1-len2;
    		if(nTimes>0)
    		{
    			for(i=len1-1;i>=nTimes;--i)
    				a2[i]=a2[i-nTimes];//朝高位移动
    			for(;i>=0;--i)
    				a2[i]=0;	//低位补零
    			len2=len1;
    		}
    		for(i=0;i<=nTimes;++i)
    		{
    			//一直减到不够减为止
                //先减去若干个 a2×(10 的nTimes次方),
                //不够减了,再减去若干个 a2×(10 的nTimes-1 次方),......
    			while((temp=Substract(a1,a2+i,len1,len2-i))>=0)  //注意while循环中的括号不能少
    			{
    				len1=temp;
    				++ans[nTimes-i];//每成功减一次,则将商的相应位加1
    			}
    		}
    		for(i=MAX;i>=0&&ans[i]==0;--i);//下面输出结果,先跳过高位0
    		if(i>=0)
    			for(;i>=0;--i)
    				printf("%d",ans[i]);
    		else
    			printf("0");
    		printf("\n");
    	}
    	return 0;
    }
    
    
    功不成,身已退
  • 相关阅读:
    .NET简谈互操作(七:数据封送之介绍)
    C# utf8编码时转换成shiftjis时出现乱码问题的处理
    .NET简谈特性(代码属性)
    著名Channel 9 主持人Robert Green 采访微软一站式示例代码库录像
    SharePoint 2007运行 Edit In DataSheet 时在IE 6下页面卡死的分析和处理方法
    截图工具
    Resharper上手指南
    .NET简谈互操作(三:基础知识之DllImport特性)
    .NET简谈互操作(五:基础知识之提升平台调用性能)
    深度训练(DotNet专场)
  • 原文地址:https://www.cnblogs.com/dongsheng/p/2617196.html
Copyright © 2020-2023  润新知