[算法]大数问题(高精度运算)

【大数相加】

【代码一】
/*********************************
*   日期:2015-01-28
*   作者:SJF0115
*   题目: 大数加法(高精度加法)
*   博客:
**********************************/
#include <iostream>
using namespace std;

string AddString(string num1,string num2){
    int len1 = num1.length();
    int len2 = num2.length();
    // 容错处理
    if(len1 <= 0){
        return num2;
    }//if
    if(len2 <= 0){
        return num1;
    }
    string result;
    int i = len1-1,j = len2-1;
    int a,b,sum,carry = 0;
    // 倒序相加
    while(i >= 0 || j >= 0 || carry > 0){
        a = i >= 0 ? num1[i] - '0' : 0;
        b = j >= 0 ? num2[j] - '0' : 0;
        // 按位相加并加上进位
        sum = a + b + carry;
        // 进位
        carry = sum / 10;
        result.insert(result.begin(),sum % 10 + '0');
        --i;
        --j;
    }//while
    return result;
}

int main(){
    string num1("72");
    string num2("874");
    string result = AddString(num1,num2);
    // 输出
    cout<<result<<endl;
    return 0;
}
【代码二】

[cpp] view
plain
copy

  1. #include<stdio.h>
  2. #include<string.h>
  3. char a[10001],b[10001],sum[10002];
  4. int BigIntegerAdd(){
  5. //两个数的长度
  6. int lena = strlen(a);
  7. int lenb = strlen(b);
  8. //进位标记
  9. int c = 0;
  10. int i,j,k;
  11. //初始化数组sum
  12. memset(sum,0,10001);
  13. //倒序相加
  14. k = 0;
  15. for(i = lena-1,j = lenb-1;i >= 0 && j >= 0;i--,j--){
  16. sum[k] = a[i] + b[j] - ‘0‘ + c;
  17. c = 0;
  18. //如果相加大于等于10
  19. if(sum[k] > ‘9‘){
  20. sum[k] -= 10;
  21. c = 1;
  22. }
  23. k++;
  24. }
  25. //a > b
  26. while(i >= 0){
  27. sum[k] = a[i] + c;
  28. c = 0;
  29. //如果相加大于等于10
  30. if(sum[k] > ‘9‘){
  31. sum[k] -= 10;
  32. c = 1;
  33. }
  34. k++;
  35. i--;
  36. }
  37. //b > a
  38. while(j >= 0){
  39. sum[k] = b[j] + c;
  40. c = 0;
  41. //如果相加大于等于10
  42. if(sum[k] > ‘9‘){
  43. sum[k] -= 10;
  44. c = 1;
  45. }
  46. k++;
  47. j--;
  48. }
  49. //如果最后两个数相加有进位的情况
  50. //例如:67 + 51:5+6有进位
  51. if(c == 1){
  52. sum[k++] = ‘1‘;
  53. }
  54. //翻转
  55. char temp;
  56. for(i = 0,j = k-1;i < j;i++,j--){
  57. temp = sum[i];
  58. sum[i] = sum[j];
  59. sum[j] = temp;
  60. }
  61. return 0;
  62. }
  63. int main(){
  64. while(scanf("%s %s",a,b) != EOF){
  65. BigIntegerAdd();
  66. puts(sum);
  67. }
  68. }

【大数相减】

[cpp] view
plain
copy

  1. /*
  2. 1.比较减数与被减数的长度,确定正负号
  3. 2.模拟减法运算
  4. (1)a[i] == b[j]
  5. (2)a[i] < b[j] //借位
  6. (3)a[i] > b[j]
  7. */
  8. #include<stdio.h>
  9. #include<string.h>
  10. char a[10001],b[10001],sum[10001],temp[10001];
  11. int BigIntegerMinus(){
  12. //两个数的长度
  13. int lena = strlen(a);
  14. int lenb = strlen(b);
  15. //借位标记
  16. int c = 0;
  17. int i,j,k,positive = 1;
  18. //判断正负号
  19. if(lena < lenb || (lena == lenb && strcmp(a,b) < 0) ){
  20. strcpy(temp,a);
  21. strcpy(a,b);
  22. strcpy(b,temp);
  23. positive = -1;//负号
  24. lena = strlen(a);
  25. lenb = strlen(b);
  26. }
  27. //倒序相减
  28. k = 0;
  29. for(i = lena-1,j = lenb-1;i >= 0 && j >= 0;i--,j--){
  30. sum[k] = a[i] - b[j] + ‘0‘ + c;
  31. c = 0;
  32. //如果相减小于0
  33. if(sum[k] < ‘0‘){
  34. sum[k] += 10;
  35. c = -1;
  36. }
  37. k++;
  38. }
  39. //a > b
  40. while(i >= 0){
  41. sum[k] = a[i] + c;
  42. c = 0;
  43. //如果相减小于0
  44. if(sum[k] < ‘0‘){
  45. sum[k] += 10;
  46. c = -1;
  47. }
  48. k++;
  49. i--;
  50. }
  51. //b > a
  52. while(j >= 0){
  53. sum[k] = b[j] + c;
  54. c = 0;
  55. //如果相减小于0
  56. if(sum[k] < ‘0‘){
  57. sum[k] += 10;
  58. c = -1;
  59. }
  60. k++;
  61. j--;
  62. }
  63. int index = k - 1;
  64. //检索高位,有可能相减为0
  65. while(sum[index] == ‘0‘ && index > 0){
  66. index--;
  67. }
  68. //正号
  69. if(positive == 1){
  70. sum[index+1] = ‘\0‘;
  71. }
  72. //负号
  73. else{
  74. sum[++index] = ‘-‘;
  75. sum[index+1] = ‘\0‘;
  76. }
  77. //翻转
  78. char t;
  79. for(i = 0,j = index;i < j;i++,j--){
  80. t = sum[i];
  81. sum[i] = sum[j];
  82. sum[j] = t;
  83. }
  84. return 0;
  85. }
  86. int main(){
  87. while(scanf("%s %s",a,b) != EOF){
  88. BigIntegerMinus();
  89. puts(sum);
  90. }
  91. }

【大数乘法】

[cpp] view
plain
copy

  1. #include<stdio.h>
  2. #include<string.h>
  3. char a[10001],b[10001],c[20002];
  4. int BigIntegerMulti()
  5. {
  6. int i,j,lena,lenb,lenc;
  7. //初始化
  8. memset(c,‘0‘,20002);
  9. //两个数的长度
  10. lena = strlen(a);
  11. lenb = strlen(b);
  12. //乘积最大位数
  13. lenc = lena + lenb - 1;
  14. //翻转
  15. char temp;
  16. for(i = 0,j = lena-1;i < j;i++,j--){
  17. temp = a[i];
  18. a[i] = a[j];
  19. a[j] = temp;
  20. }
  21. for(i = 0,j = lenb-1;i < j;i++,j--){
  22. temp = b[i];
  23. b[i] = b[j];
  24. b[j] = temp;
  25. }
  26. //倒序相乘
  27. /*
  28. 123
  29. *  54
  30. ------
  31. 492
  32. 615
  33. -----
  34. 6642
  35. */
  36. int t;
  37. for(i = 0;i < lena;i++){
  38. for(j = 0;j < lenb;j++){
  39. /* c[i+j] = (a[i] - ‘0‘) * (b[j] - ‘0‘) + c[i+j];
  40. 9 * 9 + ‘0‘ 超出char范围越界所以设置一个int临时变量t    */
  41. t = (a[i] - ‘0‘) * (b[j] - ‘0‘) + c[i+j] - ‘0‘;
  42. //进位
  43. c[i+j+1] = t / 10 + c[i+j+1];
  44. c[i+j] = t % 10 + ‘0‘;
  45. }
  46. }
  47. //确定乘积的位数
  48. while(c[lenc] == ‘0‘ && lenc >0){
  49. lenc--;
  50. }
  51. //注意:加‘\0‘
  52. c[lenc+1] = ‘\0‘;
  53. //翻转
  54. for(i = 0,j = lenc;i < j;i++,j--){
  55. temp = c[i];
  56. c[i] = c[j];
  57. c[j] = temp;
  58. }
  59. return 0;
  60. }
  61. int main(){
  62. while(scanf("%s %s",a,b) != EOF){
  63. BigIntegerMulti();
  64. puts(c);
  65. }
  66. return 0;
  67. }

自己写的如有问题,请告知一下。

时间: 2024-11-08 02:26:48

[算法]大数问题(高精度运算)的相关文章

hdu4927 Series 1(组合+公式 Java大数高精度运算)

题目链接: Series 1 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 423    Accepted Submission(s): 146 Problem Description Let A be an integral series {A1, A2, . . . , An}. The zero-order series o

大数高精度运算(模板)

前言:高精度运算.是指參与运算的数(加数.减数,因子--)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算. 模板:包含大数加减乘除.大数与int数的乘法,模板能够不断扩充. 代码: /* 所有亲測可用,可是不能用于负数的运算,仅仅能对正数进行大数运算 */ const int ten[4]= {1,10,100,1000}; const int maxl = 300; struct BigNumber { int d[maxl]; char s[maxl]; BigNumber(co

算法学习笔记(三)问题的转化与高精度运算

问题:设购票点没有任何的零钱,票价50美元,现有m人手持50美元,n人手持100美元,求这样m+n个人构成的队伍有多少种排队方法可以使得整个售票过程不中断. 分析:对于这个问题,经过简单的模拟可以发现,每个手持100的前面必须有一个手持50的,同样如果有k个手持100的连续出现,则前面至少连续k次50. 这样一来,可以设手持50元的为+1,手持100元的为-1,设ai为为第i个人所对应的值,则问题转化为数组的部分和a1+a2+...+ak≥0,其中k≤m+n,为了求这样的数列的个数,需要使用组合

整数高精度运算——加法

高精度运算是信息学的一种重要算法.这种算法使用多个存储单位进行计算,因此它的计算范围超过一般使用一个存储单位的算法.也是一些信息学竞赛的常考题目. 高精度运算主要有以下几个步骤: 1.读取字符串,转换成数字倒序存储到整数数组中: 2.运算,注意进位和借位: 3.倒序输出整数数组,加法注意最高位进位,减法注意高位中的无用的0不要输出: 高精度加法代码: #include<stdio.h>#include<string.h>char s[1000];       //数组比较大时,应作

算法竞赛之高精度以及部分组合的入门讲解

在算法竞赛之中,有时候一些题目的意思很容易就可以看出来解决步骤,但是数据却不是平常的数据量,而是高精度数据,这时候要是因为高精度的问题而使得这道题失去了AC的机会岂不是会被队友喷死,所以今天就教教大学关于高精度的一些算法吧. 个人对于高精度的算法,感觉就是很原始的小时候学习加减乘除时候的做法.怎么说呢,当然是一位一位进行处理的,可能乘法有一些什么快速乘法的,这个等后面再进行讲解,现在就说说平常自己针对高精度是怎么进行处理的吧. 首先呢,因为是高精度,那么数字的范围不大可能是int乃至__int6

大数相加—位运算

本文整理了C语言中大数据的相加算法,基于位运算来实现.亲测可用. //100位大数相加 #include <stdio.h> #include <string.h> #define Max 101//有进位101 int bigNumAdd(char a[],char b[],char sum[]) { int i=0; int c=0;//表示进位 //清0 char m[Max]={0}; char n[Max]={0}; memset(sum,0,101); //字符串反转且

一个开源的高精度运算库-GMP

https://gmplib.org/ 全称是GNU Multiple Precision Arithmetic Library,即GNU高精度算术运算库,官方网站是:http://gmplib.org/ 它的功能非常强大,接口很简单,文档详尽,有C风格的接口也有C++的精心封装后的接口,其中不但有普通的整数.实数.浮点数的高精度运算,还有随机数生成,尤其是提供了非常完备的数论中的运算接口,比如Miller-Rabin素数测试算法,大素数生成,欧几里德算法,求域中元素的逆,Jacobi符号,le

[入门]高精度运算

(本人知识 while(1)cout<<"非常"; 有限,如果你看到我有任何错漏或者不足,真的真的真的恳请大家指出,蟹蟹,我希望大家可以一起进步~) int类型的变量只能存放-2^31~2^31-1范围的数据 long long类型的变量只能存放-2^63~2^63-1范围的数据 对于大数阶乘这种肯定是存不下,因此我们需要用数组存放数据: 下面是一个高精度运算的例子: 题目描述 用高精度计算出S=1!+2!+3!+…+n! (n≤50)S=1!+2!+3!+…+n!(n≤5

高精度运算

在开发中高精度运算使用并非非常频繁,float和double的精度实际上能够满足绝大多数需要,且高精度运算效率比常规的运算要慢一点,但使用高精度运算往往是为了使用其中便捷的API.官方提供的高精度运算的类主要两个 BigInteger:当数值范围超过long时使用 BigDecimal:几乎涵盖BigInteger功能,还可以保留小数点任意位数,理论上精度无穷大,以下主要说明此类 注:两者API很相似 加减乘除 BigDecimal aaa = new BigDecimal(20); BigDe