学校数据结构的课程实验之一。
用到的数据结构:双向链表
主要功能:对由用户输入的两个任意长的整数进行加减运算
主函数:
int main()
{
short num;//临时数据段
char optr;//运算符
char ch;//临时字符接收
char choice = 'y';
while (choice == 'y')
{
List *list1 = new List();
List *list2 = new List();
cout << "请输入第一个运算数,每三位用逗号分隔,以#结束:" << endl;
cin >> ch;
if (ch == '-') list1->sign = 1;
else cin.putback(ch);
while (ch != '#')
{
cin >> num;//读入一段(3位)整数
list1->insert_tail(num);//构建第一个运算数的链表
cin >> ch;//吸收用于分隔的逗号
}
cout << "第一个运算数已保存,请输入第二个运算数:" << endl;
cin >> ch;
if (ch == '-') list2->sign = 1;
else cin.putback(ch);
while (ch != '#')
{
cin >> num;
list2->insert_tail(num);
cin >> ch;
}
cout << "第二个运算数已保存,请输入运算符(+或-):" << endl;
cin >> optr;
cout << "运算表达式为:" << endl;
list1->print();cout << endl;
cout << optr;
list2->print();
cout << endl;
List* result = operate(list1, list2, optr);
cout << "运算结果为:" << endl;
result->print();
cout << endl;
delete result, list1, list2;
cout << "是否继续?[y/n]";
cin >> choice;
}
}
链表结点定义
template<class Node_entry>//结点定义
struct Node
{
//数据成员
Node_entry entry;
Node<Node_entry> *back;
Node<Node_entry> *next;
//构造函数
Node(){}
Node(Node_entry new_entry,
Node<Node_entry> *new_back=NULL, Node<Node_entry> *new_next=NULL)
:entry(new_entry), back(new_back), next(new_next){}
};
双链表的定义
template<class List_entry>
class List
{
public:
unsigned int count;//结点个数
Node<List_entry> *head, *tail;//链表头、尾结点
short sign;//符号
List()//构造函数
{
count=0;
head=tail=NULL;
sign=0;
}
Error_code insert_tail(const List_entry x)//插在末尾
{
Node<List_entry> *new_node=new Node<List_entry>(x);
if(head==NULL) head=tail=new_node;//第一个结点
else
{
tail->next = new_node;
new_node->back = tail;
tail = new_node;
}
count++;
return success;
}
Error_code insert_head(const List_entry x)//插在开头
{
Node<List_entry> *new_node=new Node<List_entry>(x);
if (head == NULL) head = tail = new_node;//第一个结点
else
{
head->back=new_node;
new_node->next=head;
head=new_node;
}
count++;
return success;
}
Error_code delete_head()
{
Node<List_entry> *out = head;
head = head->next;
delete out;
count--;
return success;
}
Error_code print()
{
if(sign==1) cout<<'-';//打印负号
if(count==0) return fail;
if (count==1 && head->entry == 0)//头结点为0且只有这一个结点,直接输出
{
cout << head->entry;
return success;
}
while (head->entry == 0)//头结点为0,删除,直至遇到第一个不为0的头结点为止
{
delete_head();
}
Node<List_entry> *current=head;
if (count == 1)//只有一个结点,正常打印
{
cout << head->entry;
return success;
}
cout << current->entry << ',';//打印第一个结点,不做补位处理
current = current->next;
while(current != NULL && current != tail)
{
if (current->entry / 10 == 0) cout << "00";//结点为一位数时补齐三位
else if (current->entry / 100 == 0) cout << '0';//结点为两位数时补齐三位
cout<<current->entry<<',';
current=current->next;
}
//最后一段结尾没有逗号,所以单独处理
if (current->entry / 10 == 0) cout << "00";//结点为一位数时补齐三位
else if (current->entry / 100 == 0) cout << '0';//结点为两位数时补齐三位
cout<<current->entry;
return success;
}
};
List.h
用于比较链表值大小的函数
template<class List_entry>//比较链表的绝对值
Compare_result compare(List<List_entry> *l1, List<List_entry> *l2)
{
if (l1->count > l2->count) return Greater;//结点数多,一定大
else if (l1->count < l2->count) return Less;//结点数少,一定小
else//结点数一致,从头结点开始比
{
Node<List_entry> *temp1, *temp2;
temp1 = l1->head;
temp2 = l2->head;
for (unsigned int i = 0; i < l1->count; i++)
{
if (temp1->entry > temp2->entry) return Greater;
else if (temp1->entry < temp2->entry) return Less;
temp1 = temp1->next;
temp2 = temp2->next;
}
return Equal;
}
}
template<class List_entry>//运算
List<List_entry>* operate(List<List_entry> *list1, List<List_entry> *list2, char optr)
{
List<List_entry> *result = new List<List_entry>();
if (optr == '+')//输入了加法
{
if (list1->sign == 0 && list2->sign == 0)//a+b,两个正数相加
result = Plus(list1, list2);
else if (list1->sign == 0 && list2->sign == 1)//a+(-b)
{
if (compare(list1, list2) == Greater)//|a|>|b|时,将a+(-b)转为a-b
result = Minus(list1, list2);//a-b
else if (compare(list1,list2)==Less)//|a|<|b|时,转为-(b-a)
{
result = Minus(list2, list1);
result->sign = 1;//-(b-a)
}
else if (compare(list1, list2) == Equal) result->insert_head(0);//相等,差直接等于0
}
else if (list1->sign == 1 && list2->sign == 0)//(-a)+b
{
if (compare(list2, list1) == Greater)//|b|>|a|时,转为b-a
result = Minus(list2, list1);//b-a
else if (compare(list2,list1)==Less) //|b|<|a|时,转为-(a-b)
{
result = Minus(list1, list2);//-(a-b)
result->sign = 1;
}
else if (compare(list2, list1) == Equal) result->insert_head(0);//相等,差直接等于0
}
else //(-a)+(-b),转为-(a+b)
{
result = Plus(list1, list2);//-(a+b)
result->sign = 1;
}
}
else if (optr == '-')//输入了减法
{
if (list1->sign == 0 && list2->sign == 0)//a-b,需比较大小
{
if (compare(list1,list2)==Greater)
result = Minus(list1, list2);//|a|>|b|时,a-b
else if (compare(list1,list2)==Less)//|a|<|b|时,转为-(b-a)
{
result = Minus(list2, list1);//-(b-a)
result->sign = 1;
}
else if (compare(list1, list2) == Equal) result->insert_head(0);//相等,差直接等于0
}
else if (list1->sign == 0 && list2->sign == 1)//a+b,两个正数相加
result = Plus(list1, list2);
else if (list1->sign == 1 && list2->sign == 0)//(-a)-b,转为-(a+b)
{
result = Plus(list1, list2);//-(a+b)
result->sign = 1;
}
else//(-a)-(-b),即为b-a
{
if (compare(list2,list1)==Greater) result = Minus(list2, list1);//|b|>|a|时,转为b-a
else if (compare(list2,list1)==Less) //|b|<|a|时,转为-(a-b)
{
result = Minus(list1, list2);//-(a-b)
result->sign = 1;
}
else if (compare(list2, list1) == Equal) result->insert_head(0);//相等,差直接等于0
}
}
return result;
}
运算函数的辅助函数—-加法
template<class List_entry>
List<List_entry>* Plus(List<List_entry>* list1, List<List_entry>* list2)
{
List<List_entry> *result = new List<List_entry>();//存放结果的链表
Node<List_entry> *current1 = list1->tail;//初始化操作数
Node<List_entry> *current2 = list2->tail;
int carry = 0;//进位标记
List_entry tempResult;//每段的结果
int maxCount = list1->count>list2->count ? list1->count : list2->count;//最多的结点个数
Node<List_entry> *zero = new Node<List_entry>(0);//值为0的结点,用于处理早到head的那个链表
for (int i = 0; i<maxCount; i++)
{
if (current1 == NULL) current1 = zero;
if (current2 == NULL) current2 = zero;//早到的原地循环
tempResult = current1->entry + current2->entry + carry;
carry = 0;//加完进位后将carry置1
if (tempResult > limitedNum || tempResult==limitedNum)
{
carry = 1;//有进位
tempResult = tempResult % limitedNum;//取余数
}
result->insert_head(tempResult);//插入结果链表
current1 = current1->back;//向高位走
current2 = current2->back;
}
if (carry == 1) result->insert_head(1);
return result;
}
运算函数的辅助函数—-减法
template<class List_entry>
List<List_entry>* Minus(List<List_entry> *list1, List<List_entry> *list2)
{
List<List_entry> *result = new List<List_entry>();//存放结果的链表
Node<List_entry> *current1 = list1->tail;//初始化操作数
Node<List_entry> *current2 = list2->tail;
int borrow = 0;//借位标记
List_entry tempResult;//每段的结果
int maxCount = list1->count;//最多的结点个数(一定是大数减小数)
Node<List_entry> *zero = new Node<List_entry>(0);//值为0的结点,用于处理早到head的那个链表
List_entry first;//被减数
List_entry second;//减数
for (int i = 0; i<maxCount; i++)
{
if (current2 == NULL) current2 = zero;//早到的原地循环
first = current1->entry;
second = current2->entry;
first += borrow;//被减数减去借位
borrow = 0;
if (first<second)
{
borrow = -1;//有借位
first += limitedNum;
}
tempResult = first - second;
if (i == maxCount - 1 && tempResult==0) return result;//头结点为0,舍弃,直接返回
result->insert_head(tempResult);//插入结果链表
current1 = current1->back;
current2 = current2->back;
}
return result;
}