zoukankan      html  css  js  c++  java
  • 2、大数相加减

    2、大数相加减

    以前写过一篇日志,不过写的不是很全。

    http://blog.163.com/zhoumhan_0351/blog/static/399542272010328112344940/

    今天重写一下,如下:

    // JSON.cpp : 定义控制台应用程序的入口点。

    //

    #include "iostream"

    using namespace std;

    const int M = 1000; //先将定最大是位,如果要更大值,可以更改这个值

    int num1[M] = {0}, num2[M] = {0}, num3[M] = {0}; //存放两个数及生成结果

    int n1 = 0, n2 = 0, n3 = 0; //相加的两个数和位数,及结果位数

    char cn1[M] = ""cn2[M] = ""//输入的存放两个数的字符串

    int flag1 = 0, flag2 = 0, flag3 = 0; //0表示是正数,表示是负数

    char *p1 = NULL, *p2 = NULL//实际做运算的两个字符串

    int tmpflag = 0; //来记录是应当加,还是减运算,0表示相加,表示相减

    bool reverseIt = false//来标志是否需要反转,false表示不需要,true表示需要

    /*

    void calculateMulti()

    { //大数相乘算法

    for (int i = 0; i < n1; i++)

    for (int j = 0; j < n2; j++)

    {

    int temp = num1[i] * num2[j];

    num3[i + j] = num3[i + j] + temp; //处理当前位

    int temp1 = num3[i + j];

    num3[i + j] = temp1 % 10;

    num3[i + j + 1] += (temp1 / 10); //处理高位

    int temp2 = num3[i + j + 1];

    num3[i + j + 1] = temp2 % 10;

    num3[i + j + 2] += temp2 / 10; //处理次高位

    int k = 2;

    //while (num3[i + j + k] > 10 && (i + j + k) < (n1 + n2 -1))

    // {

    // int tempme = num3[i + j + k];

    // num3[i + j + k] = tempme % 10;

    // num3[i + j + k + 1] += tempme / 10; //依此处理次高位,直到最后。

    // k++;

    // }

    }

    if (0 == num3[n1+n2-1])

    n3 = n1 + n2 -2;

    else 

    n3 = n1 + n2 -1;

    for (int i = n3; i >= 0; i--)

    cout << num3[i];

    cout << endl;

    }

    */

    void calculateAdd()

    {

    n3 = n1 > n2 ? n1 : n2;

    for (int i = 0; i < n3i++)

    {

    int temp = num1[i] + num2[i];

    num3[i] = num3[i] + temp//处理当前位

    int temp1 = num3[i];

    num3[i] = temp1 % 10;

    num3[i + 1] += (temp1 / 10); //处理高位

    }

    if (0 == num3[n3]) //决定和是几位

    n3 = n3 - 1;

    else 

    n3 = n3;

    if (1 == flag3)

    cout << "-";

    for (int i = n3i >= 0; i--)

    cout << num3[i];

    cout << endl;

    }

    void calculateSubA(int num1[], int num2[])

    {

    n3 = n1 > n2 ? n1 : n2;

    for (int i = 0; i < n3i++)

    {

    ///* 

    int temp = num1[i] - num2[i];

    num3[i] = num3[i] + temp//处理当前位

    int temp1 = num3[i];

    if ((temp1 < 0) && ((i + 1) < n3))

    {

    num3[i + 1] -= 1;

    num3[i] = (temp1 + 10) % 10;

    }

    }

    }

    void convert(char cn1[], char cn2[], int n1int n2)

    {

    int count = 0;

    for (int i = n1-1; i >= 0; i--)

    num1[count++] = p1[i] - '0';

    count = 0;

    for (int i = n2-1; i >= 0; i--)

    num2[count++] = p2[i] - '0';

    }

    int doifalpha()

    {

    for (int i =0; i < n1i++)

    if (isdigit(cn1[i]) || ('-' == cn1[0]) || ('+' == cn1[0])) 

    continue;

    else 

    {

    cout << "you input include no digit alpha, please input again." << endl;

    return -1;

    }

    for (int i =0; i < n2i++)

    if (isdigit(cn2[i]) || ('-' == cn2[0]) || ('+' == cn2[0])) 

    continue;

    else 

    {

    cout << "you input include no digit alpha, please input again." << endl;

    return -1;

    }

    return 0;

    }

    void calculateSub(int num1[], int num2[])

    {

     calculateSubA(num1num2);

     if (flag3 == 1)

      cout << '-';

     for (int i = n3-1; i >= 0;i--)

      cout << num3[i];

     cout <<endl;

    }

    void PreDeal(char cn1[], char cn2[], int &n1int &n2)

    //前期处理

     p1 = cn1;

     p2 = cn2;

     if (cn1[0] == '-'//第一个数是负数

     {

      flag1 = 1;

      n1--;

      p1++;

     }

     else if (cn1[0] == '+'//第一个数是正数

     {

      flag1 = 0;

      n1--;

      p1++;

     }

     else

     {

      flag1 = 0; //正数

     }

     if (cn2[0] == '-'//第二个数是负数

     {

      flag2 = 1;

      n2--;

      p2++;

     }

     else if (cn2[0] == '+'//第二个数是正数

     {

      flag2 = 0;

      n2--;

      p2++;

     }

     else

     {

      flag2 = 0; //正数

     }

    }

    void DecideZF()

    //来决定结果是正或负

     int tempflag3 = strcmp(p1p2);

     //两个数都是负数,我们执行相加运算

     if ((1 == flag1) && (1 == flag2))

     {

      tmpflag = 0; //相加运算

      flag3 = 1; //结果是负的

     }

     //两个都是正的,招待相加运算

     if ((0 == flag1) && (0 == flag2))

     {

      tmpflag = 0;

      flag3 = 0;

     }

     //第一个是正的,第二个是负的

     if ((0 == flag1) && (1 == flag2))

     {

      tmpflag = 1;//执行减运算

      if ((n1 > n2) || ((n1 == n2) && (tempflag3 > 0)))

      {

     flag3 = 0; //正数

    reverseIt = false;//第一个数大,不需要反转

    }

    else 

    {

    flag3 = 1;

    reverseIt = true;//需要反转

    }

    }

    //第一个是负的,第二个是正的

    if ((1 == flag1) && (0 == flag2))

    {

    tmpflag = 1;//执行减运算

    if ((n1 > n2) || ((n1 == n2) && (tempflag3 > 0)))

    {

    flag3 = 1; //负数

    reverseIt = false;//第一个数大,不需要反转

    }

    else 

    {

    flag3 = 0;

    reverseIt = true;//需要反转

    }

    }

    }

    void DoTheOperation()

    {

    if (tmpflag == 1) //减运算

    {

    if (true == reverseIt//要反转

    calculateSub(num2num1); //这是相减算法

    else 

    calculateSub(num1num2); //这是相减算法

    }

    else

    {

    //加运算

    calculateAdd();

    }

    }

    int main(int argccharargv[])

    {

    while(1)

    {

    memset(num3, 0, M);

    memset(num1, 0, M);

    memset(num2, 0, M);

    memset(cn1' 'M);

    memset(cn2' 'M);

    cout << "Input two num:" << endl;

    cin >> cn1 >> cn2;

    n1 = (int)strlen(cn1);

    n2 = (int)strlen(cn2);

    int ret = doifalpha(); //是否输入非法

    if (ret == -1) return ret;

    PreDeal(cn1cn2n1n2);

    DecideZF();

    convert(cn1cn2n1n2);

    //calculateMulti(); //这是相乘算法

    //calculateAdd();

    DoTheOperation(); //进行运算

    }

    return 0;

    }

    感兴趣可以到CSDN论坛上讨论一下:

    http://topic.csdn.net/u/20100827/17/5817b294-d1ad-4da1-af7c-f1fe0187639f.html


  • 相关阅读:
    Java 中文数字转换为阿拉伯数字
    正则表达式转义符
    git .gitignore详解
    git 陷阱小记
    git log 附加命令归纳
    git 命令归纳版
    《Effective Java》 读书笔记(九)使用try-with-resources 语句替代try-finally
    架构设计 | 接口幂等性原则,防重复提交Token管理
    数据源管理 | OLAP查询引擎,ClickHouse集群化管理
    Java并发编程(04):线程间通信,等待/通知机制
  • 原文地址:https://www.cnblogs.com/mydomain/p/1813076.html
Copyright © 2011-2022 走看看