目的:使用C++模板设计单链表的抽象数据类型(ADT)。并在此基础上,使用单链表ADT的基本操作,设计并实现单链表的应用算法设计。
内容:(1)请使用模板设计单链表的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考网盘中的ADT原型文件。)
(2)ADT的应用:使用该ADT设计并实现单链表应用场合的算法设计。
应用:假设2个任意长度的整数x、y分别由带头结点的单链表A和B存储,现要求设计一个算法,实现任意长的整数进行加法运算,运算结果存储在字符串中。
参考函数原型:
template
void Long_Int_Add( LinkList &A, LinkList &B, string &result, const int &len_A, const int &len_B );
1647424776169028074.jpg
辅助函数原型:
(1)从长整数的低位开始拆分(4位为一组,即不超过9999的非负整数),依次存放在单链表的每个结点的数据域中;头结点的数据域存放正负数标志(正数或0:1,负数:-1)。
template
void Input_Int_Division( LinkList &L, string &str, int &length ); (length:长整数分割后的block数,恰为存储用单链表的长度)
(2)计算结果中间位格式控制
string Int_String( int result );
(3)两个长整数的绝对值大小比较(x>y 返回值为1;x<y 返回值为2;x=y 返回值为0;)
template
int Two_LongNum_Compare( LinkList &A, LinkList &B, const int &len_A, const int &len_B );
(4)单链表ADT基本操作:单链表的逆置(实际计算时,鉴于单链表的顺序查找的特性,存储在单链表中的长整数需逆置,由原始的高位到低位排列,逆置为低位到高位降序排列。)
template
void LinkList::ListReverse();
(5)单链表格式遍历:按照长整数的格式(4位为一组,组与组之间用,分隔)
template
bool ListTraverse(LinkList &LInt)
输入说明 :
第一行:长整数x
第二行:长整数y
输出说明 :
第一行:格式化后的长整数x(从低位到高位每4位用","分开)
第二行:格式化后的长整数y(从低位到高位每4位用","分开)
第三行:空行
第四行:格式化后的计算结果(从低位到高位每4位用","分开)
(输入与输出之间用一空行分隔)
题解
手搓了两个半小时才做出来 代码质量只能说惨不忍睹。。。
#include <iostream>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <sstream>
#include <vector>
#include <cstdio>
#include<string>
using namespace std;
#define MAXSIZE 100;
template<class ElemType>
struct LinkNode
{
ElemType data;
LinkNode<ElemType>* next;
LinkNode(LinkNode<ElemType>* ptr = NULL)
{
next = ptr;
}
LinkNode(const ElemType& item, LinkNode<ElemType>* ptr = NULL)
{
next = ptr;
data = item;
}
ElemType getData()//获取数据
{
return data;
}
void SetLink(LinkNode<ElemType>* link)
{
next = link;
}
void SetLink(ElemType value)
{
data = value;
}
};//结点定义
template<class ElemType>
class CirLinkList
{
private:
public:
LinkNode<ElemType>* head;
LinkNode<ElemType>* tail;
CirLinkList()
{
head = NULL;
tail = NULL;
}
LinkNode<ElemType>* GetHead()
{
return head;
}
LinkNode<ElemType>* GetTail()
{
return tail;
}
void SetHead(LinkNode<ElemType>* p)
{
head = p;
}
bool ListTraverse() const;
void push_back(ElemType element);
void changeTail(LinkNode<ElemType>* p);
LinkNode<ElemType>* getHead()
{
return head;
}//输出头结点
LinkNode<ElemType>* getTail()
{
return tail;
}//输出尾结点
void sum(CirLinkList <ElemType>& x)
{
LinkNode <ElemType>* p = x.getHead();
tail->next = p;
tail = x.getTail();
p = x.GetTail();
p->next = head;
p = x.getHead();
return;
}
};
template <class ElemType>
void CirLinkList<ElemType>::changeTail(LinkNode<ElemType>* p)
{
tail = p;
return;
}
template <class ElemType>
void CirLinkList<ElemType>::push_back(ElemType element)
{
if (head == NULL)
{
head = new LinkNode<ElemType>;
head->data = element;
tail = head;
tail->next = NULL;
return;
}
LinkNode<ElemType>* p = new LinkNode<ElemType>;
p->data = element;
p->next = NULL;
tail->next = p;
tail = p;
return;
}
template <class ElemType>
bool sum(CirLinkList<ElemType> A, CirLinkList<ElemType> B,int add_)
{
LinkNode <ElemType>* q, * p;
q = A.GetHead(); p = B.getHead();
while (q != NULL && p != NULL) {
if (add_ == 0) {
q->data += p->data;
if (q->data >= 10000) {
if (q->next != NULL) {
q->next->data++;
q->data -= 10000;
}
else {
q->data -= 10000;
A.push_back(1);
break;
}
}
}
else {
q->data -= p->data;
if (q->data < 0) {
if (q->next != NULL) {
q->next->data--;
q->data += 10000;
}
}
}
q = q->next; p = p->next;
}
if (add_==0&&q!=NULL)
if (q->data >= 10000) {
if (q->next != NULL) {
q->next->data++;
q->data -= 10000;
}
else {
A.push_back(1);
q->data -= 10000;
}
}
return 1;
}
template <class ElemType>
bool CirLinkList<ElemType>::ListTraverse() const
{
LinkNode<ElemType>* p;
bool fir = 0;
p = head;
if (p == NULL)
{
cout << "err" << endl;
return 0;
}
while (1)
{
if (p == NULL)
break;
if (p != head) {
if (p->data < 1000) cout << "0";
if (p->data < 100) cout << "0";
if (p->data < 10) cout << "0";
}
cout << p->data;
if (p->next != NULL)
cout << ",";
else
cout << endl;
p = p->next;
}
return 1;
}
template<class ElemType>
void ReverseList(LinkNode <ElemType> * pCur, CirLinkList <ElemType>& ListHead)
{
if ((NULL == pCur) || (NULL == pCur->next))
{
ListHead.head = pCur;
}
else
{
LinkNode <ElemType>* pNext = pCur->next;
ReverseList(pNext, ListHead); //递归逆置后继结点
pNext->next = pCur; //将后继结点指向当前结点。
pCur->next = NULL;
}
}
int main()
{
string str1, str2;
cin >> str1 >> str2;
int sum1 = 0, sum2 = 0;
int i = 0;
bool a1, a2;//0==+ 1==-
if (str1[0] == '-')
a1 = 1;
else
a1 = 0;
if (str2[0] == '-')
a2 = 1;
else
a2 = 0;
CirLinkList <int> A,B,C,D;
bool ok = 0;
if (a1) {
for (i = str1.size() - 1; i >= 1;) {
int num = 0,k=i;
num += + str1[i] - '0'; i--;
if (i >= 1) {
if (k == str1.size() - 1) sum1 = num;
num += +(str1[i] - '0') * 10; i--;
}
else {
A.push_back(num); C.push_back(num);
break;
}
if (i >= 1) {
if (k == str1.size() - 1) sum1 = num;
num += (str1[i] - '0') * 100; i--;
}
else {
A.push_back(num); C.push_back(num);
break;
}
if (i >= 1) {
if (k == str1.size() - 1) sum1 = num;
num+=(str1[i] - '0') * 1000; i--;
}
else {
A.push_back(num); C.push_back(num);
break;
}
if (k == str1.size() - 1) sum1 = num;
A.push_back(num); C.push_back(num);
}
}
else {
for (i = str1.size() - 1; i >= 0;) {
int num = 0,k=i;
num += +str1[i] - '0'; i--;
if (i >= 0) {
num += +(str1[i] - '0') * 10; i--;
if (k == str1.size() - 1) sum1 = num;
}
else {
A.push_back(num); C.push_back(num);
break;
}
if (i >= 0) {
if (k == str1.size() - 1) sum1 = num;
num += (str1[i] - '0') * 100; i--;
}
else {
A.push_back(num); C.push_back(num);
break;
}
if (i >= 0) {
if (k == str1.size() - 1) sum1 = num;
num+=(str1[i] - '0') * 1000; i--;
}
else {
A.push_back(num); C.push_back(num);
break;
}
if (k == str1.size() - 1) sum1 = num;
A.push_back(num); C.push_back(num);
}
}
if (a2) {
for (i = str2.size() - 1; i >= 1;) {
int num = 0,k=i;
num += +str2[i] - '0'; i--;
if (i >= 1) {
num += +(str2[i] - '0') * 10; i--;
if (k == str2.size() - 1) sum2 = num;
}
else {
B.push_back(num); D.push_back(num);
break;
}
if (i >= 1) {
num += (str2[i] - '0') * 100; i--;
if (k == str2.size() - 1) sum2 = num;
}
else {
B.push_back(num); D.push_back(num);
break;
}
if (i >= 1) {
num+=(str2[i] - '0') * 1000; i--;
if (k == str2.size() - 1) sum2 = num;
}
else {
B.push_back(num); D.push_back(num);
break;
}
if (k == str2.size() - 1) sum2 = num;
B.push_back(num); D.push_back(num);
}
}
else {
for (i = str2.size() - 1; i >= 0; ) {
int num = 0,k=i;
num += +str2[i] - '0'; i--;
if (i >= 0) {
num += +(str2[i] - '0') * 10; i--;
if (k == str2.size() - 1) sum2 = num;
}
else {
B.push_back(num); D.push_back(num);
break;
}
if (i >= 0) {
num += (str2[i] - '0') * 100; i--;
if (k == str2.size() - 1) sum2 = num;
}
else {
B.push_back(num); D.push_back(num);
break;
}
if (i >= 0) {
num+=(str2[i] - '0') * 1000; i--;
if (k == str2.size() - 1) sum2 = num;
}
else {
B.push_back(num); D.push_back(num);
break;
}
if (k == str2.size() - 1) sum2 = num;
B.push_back(num); D.push_back(num);
}
sum2 = (str2[0] - '0') * 1000 + (str2[1] - '0') * 100 + (str2[2] - '0') * 10 + str2[3] - '0';
}
if (sum1 < sum2) ok = 1;
if (str1.size() > str2.size()) ok = 0;
bool add_ = 0;
if (a1 == a2)
add_ = 0;
else add_ = 1;
if (a1 == 1) cout << "-";
LinkNode <int>* q = C.GetHead();
ReverseList(q, C);
C.ListTraverse();
if (a2 == 1) cout << "-";
q = D.GetHead();
ReverseList(q, D);
D.ListTraverse();
cout << endl ;
if (ok == 0) {
sum(A, B, add_);
LinkNode <int>* p = A.getHead();
ReverseList(p, A);
if (A.head->data == 0) {
cout << "0";
return 0;
}
if (a1 == 1) cout << "-";
A.ListTraverse();
}
else {
sum(B, A, add_);
LinkNode <int>* p = B.getHead();
ReverseList(p, B);
if (B.head->data == 0) {
cout << "0";
return 0;
}
if (a2 == 1) cout << "-";
B.ListTraverse();
}
return 0;
}