大整数除法

问题描述求两个大的正整数相除的商输入数据第 1行是测试数据的组数 n,每组测试数据占 2行,第 1行是被除数,第 2行是除数。

每组测试数据之间有一个空行,每行数据不超过 100个字符输出要求 n行,每组测试数据有一行输出是相应的整数商输入样例

3 2405337312963373359009260457742057439230496493930355595797660791082739646 2987192585318701752584429931160870372907079248971095012509790550883793197894

10000000000000000000000000000000000000000 10000000000

5409656775097850895687056798068970934546546575676768678435435345 1

输出样例

0 1000000000000000000000000000000 5409656775097850895687056798068970934546546575676768678435435345

解题思路

基本的思想是反复做减法,看看从被除数里昀多能减去多少个除数,商就是多少。一个一个减显然太慢,如何减得更快一些呢?以 7546除以 23为例来看一下:开始商为 0。先减去 23的 100倍,就是 2300,发现够减 3次,余下 646。于是商的值就增加 300。然后用 646减去 230,发现够减 2次,余下 186,于是商的值增加 20。昀后用 186减去 23,够减 8次,因此昀终商就是 328。

所以本题的核心是要写一个大整数的减法函数,然后反复调用该函数进行减法操作。计算除数的 10倍、100倍的时候,不用做乘法,直接在除数后面补 0即可。

参考程序

#include <iostream>
 
#include <string>
 
#define MAX_LEN 200
 
char szLine1[MAX_LEN + 10];
 
char szLine2[MAX_LEN + 10];
 
int an1[MAX_LEN + 10]; //被除数, an1[0]对应于个位
 
int an2[MAX_LEN + 10]; //除数, an2[0]对应于个位
 
int aResult[MAX_LEN + 10]; //存放商, aResult[0]对应于个位
 
/* Substract函数:长度为 nLen1的大整数 p1减去长度为 nLen2的大整数 p2
 
减的结果放在 p1里,返回值代表结果的长度
 
如不够减返回-1,正好减完返回 0
 
 p1[0]、p2[0]是个位 */
 
 int Substract( int * p1, int * p2, int nLen1, int nLen2)
 
 {
 
 int i;
 
 if( nLen1 < nLen2 )
 
  return -1;
 
 //下面判断 p1是否比 p2大,如果不是,返回-1
 
 bool bLarger = false;
 
 if( nLen1 == nLen2 ) {
 
 for( i = nLen1-1; i >= 0; i -- ) {
 
 if( p1[i] > p2[i] )
 
    bLarger = true;
 
 else if( p1[i] < p2[i] ) {
 
    if ( ! bLarger )
 
     return -1;
 
 }
 
 }
 
 }
 
 for( i = 0; i < nLen1; i ++ ) { //做减法
 
  p1[i] -= p2[i]; //要求调用本函数时给的参数能确保当 i>=nLen2时,p2[i] = 0
 
 if( p1[i] < 0 ) {
 
   p1[i]+=10;
 
   p1[i+1] --;
 
 }
 
 }
 
 for( i = nLen1 -1 ; i >= 0 ; i-- )
 
 if( p1[i] )
 
   return i + 1;
 
 return 0;
 
 }
 
 int main()
 
 {
 
 int t, n;
 
 char szBlank[20];
 
 scanf("%d", &n);
 
 for( t = 0; t < n; t ++ ) {
 
  scanf("%s", szLine1);
 
  scanf("%s", szLine2);
 
  int i, j;
 
 int nLen1 = strlen( szLine1);
 
  memset( an1, 0, sizeof(an1));
 
  memset( an2, 0, sizeof(an2));
 
  memset( aResult, 0, sizeof(aResult));
 
  j=0;
 
 for( i = nLen1 - 1;i >= 0 ; i --)
 
 an1[j++] = szLine1[i] - '0';
 
 int nLen2 = strlen(szLine2);
 
  j=0;
 
 for( i = nLen2 - 1;i >= 0 ; i --)
 
 an2[j++] = szLine2[i] - '0';
 
 if( nLen1 < nLen2 ) {
 
   printf("0\n");
 
   continue;
 
 }
 
 nLen1 = Substract( an1, an2, nLen1, nLen2) ;
 
 if( nLen1 < 0) {
 
   printf("0\n");
 
   continue;
 
 }
 
 else if( nLen1 == 0) {
 
   printf("1\n");
 
   continue;
 
 }
 
  aResult[0] ++; //减掉一次了,商加 1
 
  //减去一次后的结果长度是 nLen1
 
 int nTimes = nLen1 - nLen2;
 
 if( nTimes < 0) //减一次后就不能再减了
 
   goto OutputResult;
 
 else if( nTimes > 0 ) {
 
   //将 an2 乘以 10的某次幂,使得结果长度和 an1相同
 
 for( i = nLen1 -1; i >= 0; i -- ) {
 
    if( i >= nTimes )
 
 an2[i] = an2[i-nTimes];
 
    else
 
     an2[i] = 0;
 
 }
 
 }
 
  nLen2 = nLen1;
 
 for( j = 0 ; j <= nTimes; j ++ ) {
 
   int nTmp;
 
   //一直减到不够减为止
 
   //先减去若干个 an2×(10 的 nTimes 次方),
 
   //不够减了,再减去若干个 an2×(10 的 nTimes-1 次方),......
 
 while( (nTmp = Substract(an1, an2+j, nLen1, nLen2-j)) >= 0) {
 
    nLen1 = nTmp;
 
    aResult[nTimes-j]++; //每成功减一次,则将商的相应位加 1
 
 }
 
}
 
 OutputResult:
 
  //下面的循环统一处理进位问题
 
 for( i = 0; i < MAX_LEN; i ++ ) {
 
 if( aResult[i] >= 10 ) {
 
    aResult[i+1] += aResult[i] / 10;
 
    aResult[i] %= 10;
 
 }
 
 }
 
  //下面输出结果
 
  bool bStartOutput = false;
 
 for( i = MAX_LEN ; i >= 0; i -- )
 
   if( bStartOutput)
 
    printf("%d", aResult[i]);
 
   else if( aResult[i] ) {
 
    printf("%d", aResult[i]);
 
    bStartOutput = true;
 
 }
 
  if(! bStartOutput )
 
   printf("0\n");
 
 printf("\n");
 
 }
 system("pause");
 return 0;
 
 }

常见问题

问题一、忘了针对每一组测试数据,都要先将 an1, an2和 aResult初始化成全 0,而是一共只初始化了一次。这导致从第二组测试数据开始就都不对了。

问题二、减法处理借位的时候,容易忽略连续借位的情况,比如 10000 – 87,借位会一直进行到 1。

转载于:https://www.cnblogs.com/qnbs1/articles/1713590.html

程序设计导引及在线实践之大整数除法相关推荐

  1. 程序设计导引及在线实践_学院经纬计算学院程序设计基础与实验入选首批国家级一流本科课程...

    近日,教育部公布首批国家级一流本科课程认定清单,计算机与计算科学学院颜晖教授负责,张高燕.张泳.王云武.柳俊老师参与的<程序设计基础与实验>入选"线上线下混合式一流课程" ...

  2. 【摘录】《程序设计导引及在线实践》之排列

    问题描述 大家知道,给出正整数n,则1 到n 这n 个数可以构成n!种排列,把这些排列按照从 小到大的顺序(字典顺序)列出,如n=3 时,列出1 2 3,1 3 2,2 1 3,2 3 1,3 1 2 ...

  3. 读书-算法《程序设计导引及在线实践》-简单计算题5:装箱问题

    问题: 问题分析:主要考虑3*3的产品问题,结合实现的代码想一下,或则是想一下再结合代码 编一下代码: #include <stdio.h> void main() {int N, a, ...

  4. 1.13 编程基础之综合应用 47 大整数除法方法 python

    http://noi.openjudge.cn/ch0113/47/ """ 1.13 编程基础之综合应用 47 大整数除法方法一 http://noi.openjudg ...

  5. Bailian2737 大整数除法【大数】

    2737:大整数除法 总时间限制: 1000ms 内存限制: 65536kB 描述 求两个大的正整数相除的商. 输入 第1行是被除数,第2行是除数.每个数均不超过100位. 输出 一行,相应的商的整数 ...

  6. C++ 大整数除法 | 大整数乘法

    大整数除法 L1-046. 整除光棍 这里所谓的"光棍",并不是指单身汪啦~ 说的是全部由1组成的数字,比如1.11.111.1111等.传说任何一个光棍都能被一个不以5结尾的奇数 ...

  7. NOI1.13.47 大整数除法 题解(C++)

    NOI1.13.47 大整数除法 题解(C++) 这题一看题目就知道绝非普通的long long 或 int .这可是高精度呀. 题目 47:大整数除法 总Time Limit: 1000ms Mem ...

  8. 高精度计算-大整数除法

    问题描述 求两个大的正整数相除的商 输入数据 第 1 行是测试数据的组数 n,每组测试数据占 2 行,第 1 行是被除数,第 2 行是除数. 每组测试数据之间有一个空行,每行数据不超过 100 个字符 ...

  9. c/c++ 大整数除法

    运算思路如下思路: 以1234 / 7为例: 1与7比较, 不够除, 因此该位商为 0, 余数为1. 余数1与新位 2组合成12, 12与7比较, 够除, 商为1, 余数为5. 余数 5与新位 3组合 ...

  10. 川大c程序设计语言1在线作业,川大《C语言程序设计0008》19春在线作业1

    <C语言程序设计0008>19春在线作业2 - b: R2 o5 d+ h; y' r+ s8 D奥鹏作业答案可以联系QQ 761296021 1 s* f! ~6 @- S1 o) v1 ...

最新文章

  1. 标准评分卡分数计算原理_评分卡模型监控(前端分析)
  2. 关于枚举,enum、Enum、EnumSet、RegularEnumSet、JumboEnumSet
  3. 计算机应用12班,计算机应用二班xx毕业论文.doc
  4. idea中git分支的使用
  5. docker 打包mysql_基于docker部署mysql的数据持久化问题
  6. linux内核更新 2.6.38,Linux内核 2.6.38版本预计到四月初完成
  7. anaconda下python2和python3环境共存
  8. 大数据的5个“小观点 ”(转)
  9. halcon视觉框架源码_图像处理与机器视觉初学者学习路线
  10. (附源码)APP+springboot订餐APP 毕业设计 190711
  11. ADNI-MRI-PET-ANALYSIS
  12. 汉印全能电子面单打印机-N41
  13. 初等函数的麦克劳林级数展开+逆函数的展开求法
  14. 手持PDA助力零售卖场管理
  15. 阿拉伯数字中文oracle,【oracle】中文数字转阿拉伯数字
  16. X猜想:比尔离开后的微软帝国
  17. [ErrorCode]: UnknownHost [RequestId]: Unknown com.aliyun.oss.ClientException: srb-dev-1.LTAI5tF8g6WQ
  18. vue样式中背景图片路径_vue-cli3.0全局less样式中该如何正确设置背景图片的路径?...
  19. 【Matlab】海底声学模拟(Bellhop)以及滤波器的设计
  20. python爬虫框架feapder的使用简介

热门文章

  1. javascript 阮一峰入门教程
  2. Ubuntu16.04,16.05系列最全深度美化教你如何变得有格调
  3. 如何在电脑网页下载准考证
  4. win7安装SQL2005图文教程
  5. .bin文件打开编辑
  6. golang-thrift 使用hbase教程
  7. C语言冒泡排序算法及代码
  8. Python入门到精通(一):入门必备知识
  9. 医院耗材管理系统开发_8
  10. python frame框架,第12讲,frame 框架控件