⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 长整数加法.cpp

📁 任意长整数加法运算
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



#define TRUE 1
#define FALSE 0
#define OPERAND_NUM 2
#define POSITIVE 1
#define NEGATIVE 0



typedef int ElemType;

typedef int status;

typedef struct NodeType

    {

        ElemType data; //结点数据域

        struct NodeType *prior; //指向头结点的指针

        struct NodeType *next; //指向尾结点的指针

    } NodeType, *LinkType;  //声明指针LinkType 指向NodeType型结构体



status CreateOpHeadBuff(LinkType **, int);

status CreateOperandList(LinkType *, int);

void CreateResultList(LinkType *, LinkType *, int);

status DeleteZero(LinkType *);   //删除0元

status PushDataToList(LinkType *, int, int);

status AppendNodeToList(LinkType *, LinkType);

LinkType ComputePNList(LinkType, LinkType, int);

LinkType ComputePPNNList(LinkType, LinkType, int);

status MakeNode(LinkType *, ElemType);

status PrintList(LinkType);

status ClearMemory(LinkType *, int);

status DeleteList(LinkType);

status ErrorProcess(char[], int);



int main(void)

{

   int i, iOpNum = 2;/* 操作数的个数, 默认为2 */

   char strNum[10]/*输入的操作数*/, cOrder[5];/*退出的确认命令*/  /*储存输入字符的叔数组*/

   LinkType ResultList = NULL, /* 结果链表的头指针 */

   *ListHeadBuff = NULL; /* 指向操作数头指针 */



   do

   {

          printf("请输入需要的操作数的个数, 注意至少为2: ");

          gets(strNum); /*获取字符*/

          iOpNum = atoi(strNum);/*将字符转转为INT型*/

          } while (iOpNum < 2); /*如果输入不合法则,循环执行*/

   /* 构造操作数链表的头指针缓冲区 */

   CreateOpHeadBuff(&ListHeadBuff, iOpNum);

   /* 提示用户输入数据,并构造操作数链表 */

   while (!CreateOperandList(ListHeadBuff, iOpNum))

   {

       printf("\n出现非法输入, 需要退出吗?\n");

       printf("键入Y则退出, 键入N重新输入(Y/N):");

       gets(cOrder); /*获取输入的字符*/

       if (cOrder[0] == 'Y' || cOrder[0] == 'y')

       {

          ClearMemory(ListHeadBuff, iOpNum); /*清除LIST*/

          return 0;

       }

   }

       printf("打印输入情况:\n");

       for (i = 0; i < iOpNum; i++)

       {

           printf("- - - 第%d个操作数 - - -\n", i + 1);

           DeleteZero(ListHeadBuff + i);

           PrintList(*(ListHeadBuff + i));

       }



       /* 相加所有操作数链表的结果,并存放在ResultList中*/

       CreateResultList(&ResultList, ListHeadBuff, iOpNum);

       printf("打印结果:\n");

       PrintList(ResultList);

       ClearMemory(ListHeadBuff, iOpNum);

       DeleteList(ResultList);

       printf("程序结束");

       getch();

       return 0;

}/*main函数至此结束*/


/*-----------------------------------------------------生成结点:输入数据    数据域数量size  ->>>>>> 输出数据Linktype指针*/
   status CreateOpHeadBuff(LinkType **p, int size)  //强制指针类型转换为LinkType型输出
   {

       int i; /*声明计数器*/

       *p = (LinkType *)malloc(sizeof(LinkType) * size);   /*声名*p为结点指针*/

       if (!*p) /*[判断]---如果内存不足报错*/

       {

          printf("内存不足,分配失败!\n");

          return FALSE;

       }

       for (i = 0; i < size; i++)

          *(*p + i) = NULL;

          return TRUE;

   }


//-------------------------------------------------------------------输入数据构造链表
   status CreateOperandList(LinkType *headBuff, int iOpNum)

   {

      int i = 0, iTemp = 0,

      iNodeNum = 0, /* 记录每一个操作数链表中加入的操作数个数 */

      iSign = POSITIVE; /* 标识操作数的正(1)负(0),初始为正的 */

      char strScrNum[150], /* 用户输入的所有操作数字符 */

      *cpCurr, /* 当前操作数字符尾 */

      *cpCurrNum, /* 当前操作数字符头 */

      strTsl[7]; /* 准备转换的操作数字符 */

      LinkType NewNode;

      printf("请输入所有操作数\n");

      printf("请输入2个长整数: 1111, 2222; -3333, 4444;\n: ");

      gets(strScrNum);

      if (!ErrorProcess(strScrNum, iOpNum))
      return FALSE;   //[判断]输入的正确性

      for (cpCurr = cpCurrNum = strScrNum; *cpCurr != '\0'; cpCurr++)

      {

          if (*cpCurr == ',' || *cpCurr == ';')

          {

                  if (*(cpCurr + 1) == '\0')

                  cpCurr++;


                  strncpy(strTsl, cpCurrNum, cpCurr - cpCurrNum); //由cpCurrNum到 strTsl拷贝cpCurr - cpCurrNum长度字符

                  strTsl[cpCurr - cpCurrNum] = '\0';  //最后一位附‘0’做为判断字符终止信号

                  iTemp = atol(strTsl); //将strTsl中字符提取出并转化为整形,附给iTemp

                       if (0 > iTemp || iTemp > 9999)  //限制输入数字大小

                       {

                           printf("\n出现非法输入 2!\n");

                           return FALSE;

                       }

                              /* 为操作数链表加入结点 */
                  MakeNode(&NewNode, iTemp);                    //>>>>>>>调用函数MakeNode生成结点

                  AppendNodeToList(headBuff + i, NewNode);      //>>>>>>>调用函数AppendNodeToList

                  iNodeNum++; /* 当前链表已经加入的一个结点 */

               if (*cpCurr == ';')

               {

                 /* 将控制结点插在链表头 */

                  PushDataToList(headBuff + i, iNodeNum, iSign); //>>>>>>>调用函数PushDataToList

                  iNodeNum = 0; /* 逻辑结点个数初始化为0 */

                  iSign = POSITIVE; /* 符号标识默认为正的 */

                  if ((i + 1) < iOpNum)

                  i++; /* 标识下一个链表头指针 */

                }

           cpCurrNum = cpCurr + 1;

          }

          else if (*cpCurr == '-')

          {

            iSign = NEGATIVE; /* 符号标识改为负的 */

            cpCurr++;

            cpCurrNum = cpCurr;

          }

          else if (*cpCurr == '+');

          /* 读完后停止构造操作数链表 */

          if (*cpCurr == '\0')

          {

             PushDataToList(headBuff + i, iNodeNum, iSign);

             break;

          }

      } //for语句结束



     return TRUE;

   }



/*

* 正正,结果为正的.

* 负负,结果为负的.

* 长正短负,结果为正的.

* 长负短正,要变为长正短负,结果为负的.

* 异号时同样长

* 注意要删除每次算出的中间链表,最后传回Result

*/

   void CreateResultList(LinkType *ResultHead, LinkType *headBuff, int iOpNum)

   {

       int i, iSign;

       LinkType ResultList = NULL, TempList, CurrNode_1, CurrNode_2;

       for (ResultList = *headBuff, i = 1; i < iOpNum; i++)

       {

           TempList = ResultList;

           if (ResultList->data > 0 && (*(headBuff + i))->data > 0)/* 正正,结果为正的 */

               ResultList = ComputePPNNList(TempList, *(headBuff + i), POSITIVE);

           else if (ResultList->data < 0 &&(*(headBuff + i))->data < 0)/* 负负,结果为负的 */

               ResultList = ComputePPNNList(TempList, *(headBuff + i), NEGATIVE);

           else

           {

               if (ResultList->data + (*(headBuff + i))->data == 0)

               { /* 异号时同样长 */

                  CurrNode_1 = ResultList;

                  CurrNode_2 = *(headBuff + i);

                  do

                  { /* 直到找到第一个不等值的结点 */

                  if (CurrNode_1->data > CurrNode_2->data)

                  {

                     iSign = (ResultList->data > 0) ? POSITIVE : NEGATIVE;

                     ResultList = ComputePNList(TempList, *(headBuff + i), iSign);

                     break;

                  }

                  else if (CurrNode_1->data < CurrNode_2->data)

                  {

                     iSign = ((*(headBuff + i))->data > 0) ?POSITIVE : NEGATIVE;

                     ResultList = ComputePNList(*(headBuff + i), TempList, iSign);

                     break;

                  }

                  CurrNode_1 = CurrNode_1->next;

                  CurrNode_2 = CurrNode_2->next;

                  } while (CurrNode_1 != ResultList);

                }

               else if (fabs(ResultList->data) >fabs((*(headBuff + i))->data))

               {

                iSign = (ResultList->data > 0) ? POSITIVE : NEGATIVE;

                ResultList = ComputePNList(

                TempList, *(headBuff + i), iSign);

               }

               else if (fabs(ResultList->data) <fabs((*(headBuff + i))->data))

               {

                 iSign = ((*(headBuff + i))->data > 0) ?POSITIVE : NEGATIVE;

                 ResultList = ComputePNList(*(headBuff + i), TempList, iSign);

               }



           }

           if (*headBuff > TempList || TempList > *(headBuff + i))

           DeleteList(TempList); /* 清除上次的中间链表 */

           /* 删除多出的0,如删除0000,0010,3333中的0000为0010,3333*/

           DeleteZero(&ResultList);

         }//FOR

        *ResultHead = ResultList;

   }



/*

* 每次只处理两个操作数链表,符号相异时List_1为正的, List_2为负的

* 如果两个操作数链表不一样长则List_1为长的结果链表的结构和操作

* 数链表一样, 最后返回结果链表

*/

   LinkType ComputePNList(LinkType List_1, LinkType List_2, int iSign)

   {

     int iResult = 0, iBorrow = 0, iResultNodeNum = 0;

     LinkType CurrNodeArray[2],

     NewNode = NULL, ResultList = NULL;



     /* 初始为每一个操作数链表的尾结点地址 */

     CurrNodeArray[0] = (List_1)->prior;

     CurrNodeArray[1] = (List_2)->prior;



     while ((CurrNodeArray[0] != List_1)|| (CurrNodeArray[1] != List_2))

     {

      if (iBorrow < 0) /* 处理前一位的借位 */

       if (CurrNodeArray[0]->data > 0)

       {

         iBorrow = 0;

         iResult = -1;

       }

       else if (CurrNodeArray[0]->data == 0)

       {

       iBorrow = -1; /* 继续向高位借1位 */

       iResult = 9999;

       }



      if ((CurrNodeArray[0] != List_1)&& (CurrNodeArray[1] != List_2))

      {

        if ((CurrNodeArray[0]->data < CurrNodeArray[1]->data)&& iBorrow == 0)

        {

          iBorrow = -1; /* 不够减则向高位借1位 */

          iResult += 10000;

        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -