📄 长整数加法.cpp
字号:
#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 + -