高精度减法

简介

用于计算含有超过一般变量存放不下的非负整数

高精度加法这个过程是模拟的小学竖式减法计算

注:在本文中,我们默认输入的第一个数为被减数,且被减数大于减数

原理基本上与高精度加法相同,仅在核心代码处有些区别,因此本文较为简略,建议先阅读文章《高精度加法(C++实现)》

主要步骤

  • 清零
  • 逆置
  • 转换
  • 相减计算(包含退位)

代码实现

逆置

因为数组存放的元素顺序与我们计算的顺序是相反的,在竖式计算中我们是将其右对齐(个位对个位,十位对十位,以此类推),而读取数字后的两个数组是左对齐的,因此我们要将里面的元素逆置

  1. //参数:需要逆置的数组,数组长度
  2. void invertElem(char s[], size_t n)
  3. {
  4. size_t len = n-1;
  5. for(size_t i=0,j=len;i<j;i++,j--)
  6. {
  7. char temp = s[i];
  8. s[i] = s[j];
  9. s[j] = temp;
  10. }
  11. }

转换

为了方便计算和进位,我们需要将字符型的数字转化成实际数字

注意:这里的转换不是类型转换,例如字符类型8,我们要让它自减48,转化成ASCII码为8的对应的字符,存放元素的数组的类型并没有改变

转换必须在逆置之后。如果转换在前逆置在后,则逆置时分不清末尾的0是数字的一部分还是结束符转换后的数字

  1. //参数:数组,长度
  2. void charInt(char s[], size_t n)
  3. {
  4. for(size_t i=0; i<n; i++)
  5. s[i]-=48;
  6. }

相减

  1. int main()
  2. {
  3. while(1)
  4. {
  5. char a[1024];
  6. char b[1024];
  7. char c[2049];
  8. memset(a,0,sizeof(a));
  9. memset(b,0,sizeof(b));
  10. memset(c,0,sizeof(c));
  11. if(scanf("%s%s",a,b)==EOF) break;
  12. size_t len_a = strlen(a);
  13. size_t len_b = strlen(b);
  14. size_t max_len = len_a>len_b?len_a:len_b;
  15. invertElem(a,len_a);
  16. invertElem(b,len_b);
  17. charInt(a,len_a);
  18. charInt(b,len_b);
  19. //这部分是高精度减法的核心
  20. int carry = 0;
  21. for(size_t i=0; i<=max_len; i++)
  22. {
  23. c[i] = (a[i]-carry<b[i])?(10+a[i]-carry-b[i]):(a[i]-carry-b[i]);
  24. carry = (a[i]-carry<b[i])?1:0;
  25. }
  26. int i;
  27. for(i=max_len; i>=1&&c[i]==0; i--);
  28. for(; i>=0; i--)
  29. printf("%d", c[i]);
  30. printf("\n");
  31. }
  32. return 0;
  33. }

完整代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. //逆置
  4. void invertElem(char s[], size_t n)
  5. {
  6. size_t len = n-1;
  7. for(size_t i=0,j=len;i<j;i++,j--)
  8. {
  9. char temp = s[i];
  10. s[i] = s[j];
  11. s[j] = temp;
  12. }
  13. }
  14. //转换
  15. void charInt(char s[], size_t n)
  16. {
  17. for(size_t i=0; i<n; i++)
  18. s[i]-=48;
  19. }
  20. int main()
  21. {
  22. while(1)
  23. {
  24. char a[1024];
  25. char b[1024];
  26. char c[2049];
  27. memset(a,0,sizeof(a));
  28. memset(b,0,sizeof(b));
  29. memset(c,0,sizeof(c));
  30. if(scanf("%s%s",a,b)==EOF) break;
  31. size_t len_a = strlen(a);
  32. size_t len_b = strlen(b);
  33. size_t max_len = len_a>len_b?len_a:len_b;
  34. invertElem(a,len_a);
  35. invertElem(b,len_b);
  36. charInt(a,len_a);
  37. charInt(b,len_b);
  38. //这部分是高精度减法的核心
  39. int carry = 0;
  40. for(size_t i=0; i<=max_len; i++)
  41. {
  42. c[i] = (a[i]-carry<b[i])?(10+a[i]-carry-b[i]):(a[i]-carry-b[i]);
  43. carry = (a[i]-carry<b[i])?1:0;
  44. }
  45. int i;
  46. for(i=max_len; i>=1&&c[i]==0; i--);
  47. for(; i>=0; i--)
  48. printf("%d", c[i]);
  49. printf("\n");
  50. }
  51. return 0;
  52. }

高精度减法(C++实现)的更多相关文章

  1. HDU 5920 Ugly Problem 高精度减法大模拟 ---2016CCPC长春区域现场赛

    题目链接 题意:给定一个很大的数,把他们分为数个回文数的和,分的个数不超过50个,输出个数并输出每个数,special judge. 题解:现场赛的时候很快想出来了思路,把这个数从中间分为两部分,当位 ...

  2. 【洛谷P2142 高精度减法】

    题目描述 高精度减法 输入输出格式 输入格式: 两个整数a,b(第二个可能比第一个大) 输出格式: 结果(是负数要输出负号) 输入输出样例 输入样例#1: 复制 2 1 输出样例#1: 复制 1 说明 ...

  3. 【洛谷p2142】高精度减法

    高精度减法第一遍没有过 高精度减法[传送门] 洛谷算法标签: 总之技术都在高精上了吧. 附代码: #include<iostream> #include<cstdio> #in ...

  4. P2412高精度减法

    传送门 因为忘了带书回家,所以因为这道题我卡了半小时所以写篇博客“纪念”下 高精度减法中,如果被减数比减数小,就要用减数减去被减数.接下来的判断就是本题的核心.直接用strcmp是不行的,例如100与 ...

  5. 高精度减法--C++

    高精度减法--C++ 仿照竖式减法,先对其,再对应位相减. 算法处理时,先比较大小,用大的减小的,对应位再比较大小,用于作为借位符. #include <iostream> #includ ...

  6. P2142 高精度减法

    题目描述 高精度减法 输入输出格式 输入格式: 两个整数a,b(第二个可能比第一个大) 输出格式: 结果(是负数要输出负号) 输入输出样例 输入样例#1: 2 1 输出样例#1: 1 说明 20%数据 ...

  7. 洛谷 P2142 高精度减法(模板)

    题目描述 高精度减法 输入输出格式 输入格式: 两个整数a,b(第二个可能比第一个大) 输出格式: 结果(是负数要输出负号) 输入输出样例 输入样例#1: 2 1 输出样例#1: 1 说明 20%数据 ...

  8. 洛谷P2142 高精度减法 题解

    想找原题请点击这里:传送门 原题: 题目描述 高精度减法 输入格式 两个整数a,b(第二个可能比第一个大) 输出格式 结果(是负数要输出负号) 输入输出样例 输入 复制 输出 复制 说明/提示 %数据 ...

  9. Java实现 蓝桥杯 算法提高 高精度减法(JDK方法)

    试题 算法提高 高精度减法 问题描述 高精度减法 输入格式 两行,表示两个非负整数a.b,且有a > b. 输出格式 一行,表示a与b的差 样例输入 1234567890987654321 99 ...

  10. P2142_高精度减法(JAVA语言)

    思路:BigInteger double kill! //四行搞定 题目描述 高精度减法 输入输出格式 输入格式: 两个整数a,b(第二个可能比第一个大) 输出格式: 结果(是负数要输出负号) 输入输 ...

随机推荐

  1. 机器学习之BP神经网络

    import random import math #神经元的定义 class Neuron: def __init__(self,bias): self.bias = bias self.weigh ...

  2. Android 12(S) 图形显示系统 - BufferQueue的工作流程(八)

    题外话 最近总有一个感觉:在不断学习中,越发的感觉自己的无知,自己是不是要从"愚昧之巅"掉到"绝望之谷"了,哈哈哈 邓宁-克鲁格效应 一.前言 前面的文章中已经 ...

  3. CentOS7.5安装Ansible

    安装ansible: 查看可用的ansible版本: yum list|grep ansible   方法一: 系统可用ansible版本太低,安装epel源: yum install epel-re ...

  4. 三极管与MOS管主要参数差别及驱动电路基极(栅极)串联电阻选取原则

    三极管与MOS管都常在电路中被当做开关使用,比较起来: 1. 三极管集电极电流IC (一般为mA级别),远小于MOS管ID(一般为A级别),因此MOS管多用在大电流电路中,如电机驱动 2. 三极管耗散 ...

  5. sqlserver下载地址及密匙

    SqlServer 2017 下载地址及密钥 下载地址: ed2k://|file|cn_sql_server_2017_developer_x64_dvd_11296175.iso|17697771 ...

  6. 团队vue基础镜像选择思考

    前端镜像可以考虑使用nginx或者openresty; 镜像 大小 说明 nginx:1.20.2-alpine 8.41 MB 最小最新版本 nginx:1.21.4 50.95 MB 最新版本 n ...

  7. 为什么Java中不支持多重继承?

    我发现这个 Java 核心问题很难回答,因为你的答案可能不会让面试官满意,在大多数情况下,面试官正在寻找答案中的关键点,如果你提到这些关键点,面试官会很高兴.在 Java 中回答这种棘手问题的关键是准 ...

  8. 哪一个 bash 内置命令能够进行数学运算?

    bash shell 的内置命令 let 可以进行整型数的数学运算. #! /bin/bash - - let c=a+b - -

  9. mybatis基础(全)

    参考链接:Mybatis学习系列(一)入门简介 Mybatis学习系列(二)Mapper映射文件 Mybatis学习系列(三)动态SQL Mybatis学习系列(四)Mapper接口动态代理 Myba ...

  10. zookeeper 的应用

    不建议使用(单独)zookeeper 做分布式队列,有几点原因,以下原因摘抄于curator的官网: 1.zookeeper有1MB的传输限制.而在队列中,拥有很多的数据节点,通常包括数千个,如果有较 ...