zoukankan      html  css  js  c++  java
  • 大整数问题 (除法暂时有问题)

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 
      5 typedef struct bigInt {
      6     char* num;//指向长整数数组,序号0中保存着最低位,也就是倒序存放
      7     char minus;//符号,1表示正数,-1表示符数
      8     int digit;//保存位数
      9 }BigInt, *pBigInt;
     10 
     11 void bigIntTrans(pBigInt num1);//将字符串转化成数字表示
     12 void bigIntTrim(pBigInt num1);//整理大整数,去掉前面得0
     13 void bigIntPrint(pBigInt result);
     14 int bigIntEqual(pBigInt num1, pBigInt num2);//比较两个大整数大小
     15 void bigIntAdd(pBigInt num1, pBigInt num2, pBigInt result);
     16 void bigIntAdd1(pBigInt num1, pBigInt num2, pBigInt result);//同号相加
     17 void bigIntSub1(pBigInt num1, pBigInt num2, pBigInt result);//用于异号相加
     18 void bigIntSub(pBigInt num1, pBigInt num2, pBigInt result);//减法
     19 void bigIntMul(pBigInt num1, pBigInt num2, pBigInt result);//乘法
     20 void bigIntDiv(pBigInt num1, pBigInt num2, pBigInt result, pBigInt residue);//除法
     21 
     22 int main(void) {
     23     bigInt num1, num2, result, residue;
     24     int i = 0, len;
     25     char op;
     26     
     27     printf("输入最大数的位数:");
     28     scanf("%d", &len);
     29     if (!(num1.num = (char*)malloc(sizeof(char) * (len + 1)))) { printf("内存分配失败
    "); exit(0); }
     30     num1.digit = len + 1;
     31     if (!(num2.num = (char*)malloc(sizeof(char) * (len + 1)))) { printf("内存分配失败
    "); exit(0); }
     32     num2.digit = len + 1;
     33     if (!(result.num = (char*)malloc(sizeof(char) * (len + 1)))) { printf("内存分配失败
    "); exit(0); }
     34     result.digit = 2 * len + 1;
     35     for (i = 0; i < result.digit; i++)    result.num[i] = 0;
     36     printf("选择大整数运算(+,-,*,/): ");
     37     fflush(stdin);//刷新标准输入缓冲区,把输入缓冲区里的东西丢弃
     38     scanf(" %c", &op);
     39     switch (op) {
     40     case '+':
     41         printf("
    输入被加数:");    scanf("%s", num1.num);
     42         printf("
    输入加数:");    scanf("%s", num2.num);
     43         bigIntTrans(&num1);
     44         bigIntTrans(&num2);
     45         bigIntAdd(&num1, &num2, &result);
     46         break;
     47     case '-':
     48         printf("
    输入被减数:");    scanf("%s", num1.num);
     49         printf("
    输入减数:");    scanf("%s", num2.num);
     50         bigIntTrans(&num1);
     51         bigIntTrans(&num2);
     52         bigIntSub(&num1, &num2, &result);
     53         break;
     54     case '*':
     55         printf("
    输入被乘数:");    scanf("%s", num1.num);
     56         printf("
    输入乘数:");    scanf("%s", num2.num);
     57         bigIntTrans(&num1);
     58         bigIntTrans(&num2);
     59         bigIntMul(&num1, &num2, &result);
     60         break;
     61     case '/':
     62         printf("
    输入被除数:");    scanf("%s", num1.num);
     63         printf("
    输入除数:");    scanf("%s", num2.num);
     64         bigIntTrans(&num1);
     65         bigIntTrans(&num2);
     66         if (num2.digit == 1 && num2.num[0] == '0')    printf("除数不能为0!
    ");
     67         else bigIntDiv(&num1, &num2, &result, &residue);
     68         break;
     69     }
     70 
     71     if (op == '/') {
     72         if (!(num2.digit == 1 && num2.num[0] == '0')) {
     73             printf("商:");    bigIntPrint(&result);
     74             printf("	余数:");    bigIntPrint(&residue);
     75         }
     76     }
     77     else {printf("结果:");    bigIntPrint(&result);}
     78 
     79 
     80     return 0;
     81 }
     82 
     83 void bigIntTrans(pBigInt num1) {
     84     char* t;
     85     int i, k, len;
     86 
     87     len = strlen(num1->num);
     88     if (!(t = (char*)malloc(sizeof(char) * len))){printf("内存分配失败!
    ");exit(0); }
     89     i = 0;
     90     num1->minus = 1;//默认为正
     91     if (num1->num[0] == '-') { num1->minus = -1; i++; }//若第一个字符试'-',那么则是负数
     92     k = 0;
     93     while (num1->num[i] != '') {
     94         if (num1->num[i] >= '0' && num1->num[i] <= '9') { t[k++] = num1->num[i] - '0'; }//将ASCII码转化成对应得数字
     95         i++;
     96     }
     97 
     98     for (i = 0; i < num1->digit; i++)    num1->num[i] = 0;//数组清空
     99     num1->digit = k;//转换后得位数
    100     for (i = 0, k--; k >= 0; k--, i++)    num1->num[i] = t[k];//将临时数组 各位 反置 后存到num中
    101 
    102     bigIntTrim(num1);
    103 
    104 }
    105 
    106 void bigIntTrim(pBigInt num1) {
    107     int i;
    108     //从高位检查是否为0
    109     for (i = num1->digit - 1; i >= 0; i--) { if (num1->num[i] != 0)    break; }//遇到不为0得最高位,跳出循环
    110     if (i < 0) { num1->digit = 1; num1->num[0] = 0; }
    111     else num1->digit = i + 1;//余数位数,因为i对应的是下标,比如对应的i=4,那么下标为0,1,2,3,4的位置上都有数,则为5位数
    112 
    113 }
    114 
    115 void bigIntPrint(pBigInt result) {
    116     int i;
    117 
    118     if (result->minus == -1) printf("-"); 
    119     if (result->digit == 1 && result->num[0] == 0) printf("0
    ");
    120     else {
    121         for (i = result->digit - 1; i >= 0; i--)
    122             printf("%d", result->num[i]);
    123     }
    124 }
    125 
    126 int bigIntEqual(pBigInt num1, pBigInt num2) {
    127     int i;
    128 
    129     if (num1->digit > num2->digit)    return 1;
    130     else if (num1->digit < num2->digit)    return -1;
    131     else {
    132         i = num1->digit - 1;
    133         while (i >= 0) {
    134             if (num1->num[i] > num2->num[i])    return 1;
    135             else if (num1->num[i] < num2->num[i])    return -1;
    136             else i--;
    137         }
    138     }
    139     return 0;
    140 }
    141 
    142 void bigIntAdd(pBigInt num1, pBigInt num2, pBigInt result) {
    143     int i = bigIntEqual(num1, num2);
    144 
    145     if (i < 0) { pBigInt t; t = num1; num1 = num2; num2 = t; }
    146     if (num1->minus * num2->minus < 0) {//符号相同,则加法,不同则减法
    147         if (i == 0) {//如果两个数是相等的
    148             result->digit = 1;//结果长度为1位数,就是数值0
    149             result->minus = 1;//结果为正号
    150             result->num[0] = 0;//结果为0
    151             return;
    152         }
    153         bigIntSub1(num1, num2, result);//减法
    154     }
    155     else bigIntAdd1(num1, num2, result);
    156 }
    157 
    158 void bigIntAdd1(pBigInt num1, pBigInt num2, pBigInt result) {
    159     int i, carry = 0;//carry代表的 进位
    160     
    161     result->minus = num1->minus;
    162     for (i = 0; i < num1->digit; i++) { result->num[i] = num1->num[i]; }
    163     for (i = 0; i < num2->digit; i++) {
    164         result->num[i] = result->num[i] + num2->num[i] + carry;//将对应的数和进位数相加
    165         carry = result->num[i] / 10;//计算进位数据
    166         result->num[i] = result->num[i] % 10;//保留一位
    167     }
    168 
    169     if (carry)    result->num[i] = result->num[i] + carry;//若最后还有进位
    170     bigIntTrim(result);
    171 }
    172 
    173 void bigIntSub1(pBigInt num1, pBigInt num2, pBigInt result) {//异号相减函数
    174     int i, borrow = 0;//borrow低位的借位
    175 
    176     result->minus = num1->minus;
    177     for (i = 0; i < num1->digit; i++)    result->num[i] = num1->num[i];
    178     for (i = 0; i <= num2->digit; i++) {
    179         result->num[i] = result->num[i] - num2->num[i] - borrow;
    180         if (result->num[i] < 0) {
    181             result->num[i] = 10 + result->num[i];
    182             borrow = 1;
    183         }
    184         else borrow = 0;
    185     }
    186 
    187     if (borrow == 1)    result->num[i] = result->num[i] - borrow;
    188     i = num1->digit;
    189     while (i > 0) {
    190         if (result->num[i] == 0)    i--;
    191         else break;
    192     }
    193 
    194     result->digit = i + 1;
    195     bigIntTrim(result);
    196 }
    197 
    198 void bigIntSub(pBigInt num1, pBigInt num2, pBigInt result) {
    199     num2->minus = -1 * num2->minus;//将减数符号取反
    200     bigIntAdd(num1, num2, result);
    201 }
    202 
    203 void bigIntMul(pBigInt num1, pBigInt num2, pBigInt result) {
    204     char carry, t;
    205     int i, j, pos;
    206 
    207     for (i = 0; i < num1->digit + num2->digit; i++)    result->num[i] = 0;//结果数组清零
    208     for (i = 0; i < num2->digit; i++) {
    209         carry = 0;//清除进位
    210         for (j = 0; j < num1->digit; j++) {
    211             t = num2->num[i] * num1->num[j] + carry;//两个数相乘,加上进位
    212             carry = t / 10;//进位
    213             t %= 10;//计算当前位的值
    214             pos = i + j;//看t应该加在哪个位上
    215             result->num[pos] += t;
    216             carry = carry + result->num[pos] / 10;//主要防止num[pos]大于等于10
    217             result->num[pos] = result->num[pos] % 10;
    218         }
    219 
    220         if (carry > 0) {
    221             result->num[i + j] = carry;//加上最高位的进位
    222             result->digit = i + j + 1;
    223         }
    224         else result->digit = i + j;
    225     }
    226 
    227     result->minus = num1->minus * num2->minus;
    228 }
    229 
    230 void bigIntDiv(pBigInt num1, pBigInt num2, pBigInt result, pBigInt residue) {
    231     bigInt quo1, quo2, residue1;
    232     int i, j, k, m;//k保存试商结果,m保存商的位数
    233     char t;
    234 
    235     result->minus = num1->minus * num2->minus;
    236     residue->num = (char*)malloc(sizeof(char) * (num2->digit + 1));//分配余数空间
    237     residue->digit = num2->digit + 1;
    238     for (i = 0; i < residue->digit; i++)    residue->num[i] = 0;//将余数清零
    239     m = 0;
    240     for (i = num1->digit - 1; i >= 0; i--) {
    241         for (j = residue->digit - 1; j > 0; j--) residue->num[j] = residue->num[j - 1];//移余数 (有问题,等会试一下)
    242         residue->num[0] = num1->num[i];
    243         bigIntTrim(residue);//整理余数
    244         k = 0;
    245         while (bigIntEqual(residue, num2) >= 0) {
    246             bigIntSub1(residue, num2, residue);
    247             k++;
    248         }
    249         result->num[m++] = k;
    250 
    251     }
    252 
    253     result->digit = m;
    254     for (i = 0; i < m / 2; i++) {
    255         t = result->num[i];
    256         result->num[i] = result->num[m - 1 - i];
    257         result->num[m - 1 - i] = t;
    258     }
    259 
    260     bigIntTrim(result);
    261     bigIntTrim(residue);
    262 }
  • 相关阅读:
    38. Count and Say(C++)
    35. Search Insert Position(C++)
    29. Divide Two Integers(C++)
    c++读取utf-8格式中英文混合string
    一种局部二值化算法:Sauvola算法
    Ubuntu 1804 本地显示远程服务器文件
    caffe 预训练 或者Fine-Tuning 操作
    caffe/blob.hpp:9:34: fatal error: caffe/proto/caffe.pb.h: 没有那个文件或目录
    转载---LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别
    [leetcode-921-Minimum Add to Make Parentheses Valid]
  • 原文地址:https://www.cnblogs.com/letianpaiai/p/12903685.html
Copyright © 2011-2022 走看看