zoukankan      html  css  js  c++  java
  • 大数减法(A

    解题思路

    flagA为0表示A为正整数,为-1表示A为负整数;

    flagB为0表示B为正整数,为2表示B为负整数;

    而 flag = flagA + flagB。

    当 flag == 0 表示数A为正整数,数B为正整数

    则A - B 可能是正整数或负整数。

    当 flag == 1 表示数A为负整数,数B为负整数

    则A - B 可能是正整数或负整数。

    因为差值可能是正整数,也可能是负整数,所以采用如下方法:

    (1) 先判断被减数和减数哪⼀个位数⻓。若被减数位数⻓是正常的减法;若减数位数⻓,则⽤被减数减去减数,最后还要加上负号。

    (2) 当两数位数⻓度相等时,最好⽐较哪⼀个数⼤,否则负号处理会很繁琐。处理每⼀项时,如果前⼀位相减有借位,就先减去上⼀位的借位,⽆则不减,再去判断是否能够减开被减数,如果减不开,就要借位后再去减,同时置借位为1,否则置借位为0。

    当 flag == -1 表示数A为负整数,数B为正整数

    则A - B 一定为负整数。

    由于计算时数字去掉了负号,可以则先相加,最后加上负号。

    如-3 - 18,是3 + 18 = 21,再加上负号,即-21。

    当 flag == 2 表示数A为正整数,数B为负整数

    则A - B 一定为正整数。

    由于计算时数字去掉了负号,则可以直接相加。

    如3 - (-18),是3 + 18 = 21。

    样例

    输入1:

    -3 98
    

    输出1:

    -3 - 98 = -101
    

    输入2:

    -3 -98
    

    输出2:

    -3 - (-98) = 95
    

    输入3:

    3 98
    

    输出3:

    3 - 98 = -95
    

    代码实现

    #include<stdio.h>
    #include<string.h>
    #define NUM_MAX 1000                // 大数的最大位数
    
    /*
     大数减法
     参数:
     numA为第一个大数
     numB为第二个大数
     difference保存相减的结果  即:numA - numB = difference
     lenA为char指针的长度
     lenB为char指针的长度
     flag为-1表示A为负整数、B为正整数,为0表示A与B均为正整数,
     为1表示A与B均为负整数,为2表示A为正整数、B为负整数
     返回值:返回数组difference的有效长度,即计算结果的位数
     */
    
    void Minus(char* numA, char* numB, int* difference, int lenA, int lenB, int flag)
    {
        char* temp = NULL;
        int symbol = 0;                             // symbol为0表示计算结果是正整数,为1表示结果是负整数
        int tempFlag = 0;                           // 临时标志
        
        int maxLen = lenA > lenB ? lenA : lenB;     // 取字符串numA与numB的最大长度
        
        // flag == 0 表示数A为正整数,数B为正整数,则A - B 可能是正整数或负整数
        // flag == 1 表示数A为负整数,数B为负整数,则A - B 可能是正整数或负整数
        if (flag == 0 || flag == 1)
        {
            // 如果被减数位数小于减数
            if (lenA < lenB)
            {
                tempFlag = 1;
                // 交换两数,方便计算
                temp = numA;
                numA = numB;
                numB = temp;
                
                maxLen = lenA;
                lenA = lenB;
                lenB = maxLen;
            }
            else if (lenA == lenB)                  // 如果被减数位数等于减数的位数
            {
                for (int i = 0; i < lenA; i++)
                {
                    if (numA[i] == numB[i])
                    {
                        continue;
                    }
                    else if (numA[i] > numB[i])
                    {
                        tempFlag = 0;
                        break;
                    }
                    else
                    {
                        tempFlag = 1;
                        temp = numA;
                        numA = numB;
                        numB = temp;
                        break;
                    }
                }
            }
        }
        
        
        // 数A与B均为正整数
        if (flag == 0)
        {
            if (tempFlag == 0)
            {
                symbol = 0;
            }
            else
            {
                symbol = 1;
            }
        }
        else if (flag == 1)                         // 数A与B均为负整数
        {
            if (tempFlag == 0)
            {
                symbol = 1;
            }
            else
            {
                symbol = 0;
            }
        }
        else if (flag == -1)                        // 数A为负整数,数B为正整数,则A - B 一定为负整数
        {
            symbol = 1;
        }
        else                                        // flag == 2表示数A为正整数,数B为负整数,则A - B 一定为正整数
        {
            symbol = 0;
        }
        
        int l = 0;
        int k = 0;
        int array[NUM_MAX] = {0};
        
        // 将numA字符数组的字符数字转换为整型数字,且逆向保存到整型数组sum中,即低位在前,高位在后
        for (int i = lenA - 1; i >= 0; i--)
        {
            difference[k++] = numA[i] - '0';               // 可以使用'9' - '0' = 9的方式将字符数字转换为整型数字
        }
        
        // 转换第二个数
        for (int j = lenB - 1; j >= 0; j--)
        {
            array[l++] = numB[j] - '0';
        }
        
        // 两数相减
        // flag == 0 表示数A为正整数,数B为正整数,则A - B 可能是正整数或负整数
        // flag == 1 表示数A为负整数,数B为负整数,则A - B 可能是正整数或负整数
        // 这种情况采用上面的方法:先比较数A与数B的长度,长度相等的话,从第一个元素开始逐位比较值的大小
        // 最终,会用较大的数减去较小的数
        
        // flag == -1 表示数A为负整数,数B为正整数,则A - B 一定为负整数
        // 由于这里数字去掉了负号,则先计算A + B之和,最后输出的时候再加上负号
        // 如-3 - 8,在这里是3 + 8 = 11,再加上负号,即-11
        
        // flag == 2 表示数A为正整数,数B为负整数,则A - B 一定为正整数
        // 由于这里数字去掉了负号,则计算A + B之和
        // 如3 - (-8),在这里是3 + 8 = 11,不用加负号
        for (int i = 0; i <= maxLen; i++)
        {
            if (flag == 0 || flag == 1)
            {
                difference[i] -= array[i];             // 两个数从低位开始相减
                if (difference[i] < 0)                 // 判断是否有借位
                {
                    difference[i] += 10;
                    difference[i+1]--;
                }
            }
            else if (flag == -1 || flag == 2)
            {
                difference[i] += array[i];             // 两个数从低位开始相加
                if (difference[i] > 9)                 // 判断是否有进位
                {
                    difference[i] %= 10;
                    difference[i+1]++;
                }
            }
            
        }
        
        // 计算结果为负数
        if (symbol == 1)
        {
            // 高位maxLen - 1没有值
            if(difference[maxLen] == 0)
            {
                // 在⾼位添加⼀个 -1 表示负数
                difference[maxLen] = -1;
                maxLen++;
            }
            else                                // 高位maxLen - 1有值
            {
                // 在⾼位添加⼀个 -1 表示负数
                difference[maxLen + 1] = -1;
                maxLen = maxLen + 1 + 1;
            }
        }
        else                                    // 计算结果为正数
        {
            if(difference[maxLen] == 0)
            {
                maxLen++;
            }
            else
            {
                maxLen = maxLen + 1 + 1;
            }
        }
        
        int i = 0;
        
        // 根据高位是否是-1判断是否是负数
        if (difference[i = maxLen - 1] < 0)
        {
            printf("-");                        // 输出负号
            i--;
        }
        else
        {
            i = maxLen;
        }
        
        // 高位是0的话不输出,从第一个不是0的位开始输出
        while (difference[i] == 0)
        {
            i--;
        }
        
        // 打印计算结果
        for ( ; i >= 0; i--)
        {
            printf("%d", difference[i]);
        }
        
    }
    
    int main()
    {
        char strA[NUM_MAX] = {0};
        char strB[NUM_MAX] = {0};
        
        while (scanf("%s%s", strA, strB) != EOF)
        {
            char numA[NUM_MAX] = {0};
            char numB[NUM_MAX] = {0};
            int difference[NUM_MAX] = {0};      // 存放计算的结果,低位在前,高位在后,即sum[0]是低位
            int flag = 0;
            int flagA = 0;                      // flagA为0表示A为正整数,为-1表示A为负整数
            int flagB = 0;                      // flagB为0表示B为正整数,为2表示B为负整数
            int lenA = strlen(strA);            // 计算数组numA的长度,即数A的位数
            int lenB = strlen(strB);            // 计算数组numB的长度,即数B的位数
            
            // 若为负数,去掉负号,且数字所在字符长度减1
            if (strA[0] == '-')
            {
                flagA = -1;
                lenA--;
            }
            if (strB[0] == '-')
            {
                flagB = 2;
                lenB--;
            }
            
            // flag为-1表示A为负整数、B为正整数,为0表示A与B均为正整数,
            // 为1表示A与B均为负整数,为2表示A为正整数、B为负整数
            flag = flagA + flagB;
            
            // 将strA与strB字符串重新存储到numA与numB字符串中,主要为了重新存储去掉负号的字符串
            for (int i = lenA - 1; i >= 0; i--)
            {
                if (flagA == -1)
                {
                    numA[i] = strA[i+1];
                }
                else
                {
                    numA[i] = strA[i];
                }
            }
            
            for (int j = lenB - 1; j >= 0; j--)
            {
                if (flagB == 2)
                {
                    numB[j] = strB[j+1];
                }
                else
                {
                    numB[j] = strB[j];
                }
            }
            
            if (flagB == 2)
            {
                printf("%s - (%s) = ", strA, strB);
            }
            else
            {
                printf("%s - %s = ", strA, strB);
            }
            
            // 调用大数减法函数
            Minus(numA, numB, difference, lenA, lenB, flag);
            
            // 换行
            printf("
    ");
        }
        
        return 0;
    }
    

    个人主页:

    www.codeapes.cn

  • 相关阅读:
    Session的使用与管理
    CSS控制文字,超出部分显示省略号
    MP4 文件前端获取视频封面
    prefetch预加载功能使用
    react-学习之路-react-router-解决问题记录
    如何将一个div盒子水平垂直都居中?
    window下查看端口号,并删除对应进程
    判断js 验证字符串里面有没有包含汉字:
    vue 现有的$变量 以及如何添加全局变量
    与人言
  • 原文地址:https://www.cnblogs.com/codeapes666/p/12093746.html
Copyright © 2011-2022 走看看