用链表实现大整数相加减(C++大作业)
题目要求:
代码实现:
#include <cstdio>
#include <cstdlib>
constexpr bool Positive = 0;
constexpr bool Negative = 1;
template <typename DataType>
struct Node
{
DataType data;
Node* prev;
Node* next;
Node(DataType data = DataType(), Node* prev = nullptr, Node* next = nullptr) : data(data), prev(prev), next(next) {}
};
template <typename DataType>
class List
{
public:
List() : symbol(Positive), size(0)
{
header = new Node<DataType>;
tailer = new Node<DataType>;
header->next = tailer;
tailer->prev = header;
}
void readInteger()
{
header = new Node<int>;
tailer = new Node<int>;
header->next = tailer;
tailer->prev = header;
Node<int>* current = header;
char ch = 0;
ch = getchar();
if (ch == '-')
{
symbol = Negative;
ch = getchar();
}
while (ch != '\n')
{
if (ch == ',')
{
ch = getchar();
continue;
}
Node<int>* node = new Node<int>(ch - '0', current, tailer);
current->next = node;
tailer->prev = node;
current = node;
ch = getchar();
++size;
}
}
bool sign()
{
return this->symbol;
}
int length()
{
return this->size;
}
Node<DataType>* cbegin()
{
return this->header;
}
Node<DataType>* cend()
{
return this->tailer;
}
void setSign(bool symbol)
{
this->symbol = symbol;
return;
}
void setLength(int size)
{
this->size = size;
return;
}
void setHead(Node<DataType>* header)
{
this->header = header;
return;
}
void setTail(Node<DataType>* tailer)
{
this->tailer = tailer;
return;
}
private:
bool symbol;
int size;
Node<DataType>* header;
Node<DataType>* tailer;
};
class BigInteger
{
public:
BigInteger(bool symbol = Positive, int size = 1) : symbol(symbol), size(size)
{
header = new Node<int>;
tailer = new Node<int>;
header->next = tailer;
tailer->prev = header;
Node<int>* node = new Node<int>(0, header, tailer);
header->next = node;
tailer->prev = node;
}
BigInteger(bool symbol, int size, Node<int>* header, Node<int>* tailer) : symbol(symbol), size(size), header(header), tailer(tailer) {}
BigInteger(List<int> list) : symbol(list.sign()), size(list.length()), header(list.cbegin()), tailer(list.cend()) {}
bool sign()
{
return this->symbol;
}
int length()
{
return this->size;
}
Node<int>* cbegin()
{
return this->header;
}
Node<int>* cend()
{
return this->tailer;
}
void setSign(bool symbol)
{
this->symbol = symbol;
return;
}
void setLength(int size)
{
this->size = size;
return;
}
void setHead(Node<int>* header)
{
this->header = header;
return;
}
void setTail(Node<int>* tailer)
{
this->tailer = tailer;
return;
}
void print()
{
if (header != nullptr && header->next != nullptr)
{
Node<int>* current = header->next;
int sum = symbol + size;
int tmp = sum;
if (symbol == Negative)
{
putchar('-');
--sum;
}
while (sum)
{
if (sum % 3 == 0 && sum != tmp)
{
putchar(',');
}
putchar(current->data + '0');
current = current->next;
--sum;
}
putchar('\n');
}
}
void print(Node<int>* head)
{
while (head != nullptr)
{
printf("%d", head->data);
head = head->next;
}
printf("\n");
return;
}
void print(Node<int>* tail, int val)
{
while (tail != nullptr)
{
printf("%d", tail->data);
tail = tail->prev;
}
printf("\n");
return;
}
void print(BigInteger bigInteger)
{
if (bigInteger.cbegin() != nullptr && bigInteger.cbegin()->next != nullptr)
{
Node<int>* current = bigInteger.cbegin()->next;
int sum = bigInteger.sign() + bigInteger.length();
int tmp = sum;
if (bigInteger.sign())
{
putchar('-');
--sum;
}
while (sum)
{
if (sum % 3 == 0 && sum != tmp)
{
putchar(',');
}
putchar(current->data + '0');
current = current->next;
--sum;
}
putchar('\n');
}
}
private:
bool symbol;
int size;
Node<int>* header;
Node<int>* tailer;
};
class Calculation
{
public:
void print(BigInteger bigInteger)
{
if (bigInteger.cbegin() != nullptr && bigInteger.cbegin()->next != nullptr)
{
Node<int>* current = bigInteger.cbegin()->next;
int sum = bigInteger.sign() + bigInteger.length();
int tmp = sum;
if (bigInteger.sign())
{
putchar('-');
--sum;
}
while (sum)
{
if (sum % 3 == 0 && sum != tmp)
{
putchar(',');
}
putchar(current->data + '0');
current = current->next;
--sum;
}
putchar('\n');
}
}
BigInteger add(BigInteger bigInteger1, BigInteger bigInteger2)
{
if (bigInteger1.sign() == Positive && bigInteger2.sign() == Positive)
{
Node<int>* node1 = new Node<int>;
Node<int>* node2 = new Node<int>;
Node<int>* head = new Node<int>;
Node<int>* tail = new Node<int>;
head->next = tail;
tail->prev = head;
Node<int>* curr = tail;
if (bigInteger1.cend() != nullptr && bigInteger1.cend()->prev != nullptr)
{
node1 = bigInteger1.cend()->prev;
}
if (bigInteger2.cend() != nullptr && bigInteger2.cend()->prev != nullptr)
{
node2 = bigInteger2.cend()->prev;
}
int carry = 0;
int sum = 0;
int size = 0;
while (node1 != bigInteger1.cbegin() || node2 != bigInteger2.cbegin() || carry > 0)
{
sum = (node1 == bigInteger1.cbegin() ? 0 : node1->data) + (node2 == bigInteger2.cbegin() ? 0 : node2->data) + carry;
carry = sum / 10;
sum %= 10;
Node<int>* node = new Node<int>(sum, head, curr);
++size;
head->next = node;
curr->prev = node;
curr = node;
node1 = node1 == bigInteger1.cbegin() ? bigInteger1.cbegin() : node1->prev;
node2 = node2 == bigInteger2.cbegin() ? bigInteger2.cbegin() : node2->prev;
}
return BigInteger(Positive, size, head, tail);
}
if (bigInteger1.sign() == Negative && bigInteger2.sign() == Negative)
{
return opposite(add(opposite(bigInteger1), opposite(bigInteger2)));
}
if (bigInteger1.sign() == Positive && bigInteger2.sign() == Negative)
{
return sub(bigInteger1, opposite(bigInteger2));
}
if (bigInteger1.sign() == Negative && bigInteger2.sign() == Positive)
{
return add(bigInteger2, bigInteger1);
}
return BigInteger();
}
int compare(BigInteger bigInteger1, BigInteger bigInteger2)
{
if (bigInteger1.sign() == Positive && bigInteger2.sign() == Negative)
{
return 1;
}
if (bigInteger1.sign() == Negative && bigInteger2.sign() == Positive)
{
return -1;
}
if (bigInteger1.sign() == Positive && bigInteger2.sign() == Positive)
{
if (bigInteger1.length() > bigInteger2.length())
{
return 1;
}
if (bigInteger1.length() < bigInteger2.length())
{
return -1;
}
Node<int>* node1 = new Node<int>;
Node<int>* node2 = new Node<int>;
if (bigInteger1.cbegin() != nullptr && bigInteger1.cbegin()->next != nullptr)
{
node1 = bigInteger1.cbegin()->next;
}
if (bigInteger2.cbegin() != nullptr && bigInteger2.cbegin()->next != nullptr)
{
node2 = bigInteger2.cbegin()->next;
}
while (node1 != bigInteger1.cend())
{
if (node1->data > node2->data)
{
return 1;
}
if (node1->data < node2->data)
{
return -1;
}
node1 = node1->next;
node2 = node2->next;
}
return 0;
}
if (bigInteger1.sign() == Negative && bigInteger2.sign() == Negative)
{
if (bigInteger1.length() > bigInteger2.length())
{
return -1;
}
if (bigInteger1.length() < bigInteger2.length())
{
return 1;
}
Node<int>* node1 = new Node<int>;
Node<int>* node2 = new Node<int>;
if (bigInteger1.cbegin() != nullptr && bigInteger1.cbegin()->next != nullptr)
{
node1 = bigInteger1.cbegin()->next;
}
if (bigInteger2.cbegin() != nullptr && bigInteger2.cbegin()->next != nullptr)
{
node2 = bigInteger2.cbegin()->next;
}
while (node1 != bigInteger1.cend())
{
if (node1->data > node2->data)
{
return -1;
}
if (node1->data < node2->data)
{
return 1;
}
}
return 0;
}
return 0;
}
BigInteger sub(BigInteger bigInteger1, BigInteger bigInteger2)
{
if (bigInteger1.sign() == Positive && bigInteger2.sign() == Positive)
{
if (compare(bigInteger1, bigInteger2) == 1)
{
Node<int>* node1 = new Node<int>;
Node<int>* node2 = new Node<int>;
Node<int>* head = new Node<int>;
Node<int>* tail = new Node<int>;
head->next = tail;
tail->prev = head;
Node<int>* curr = tail;
if (bigInteger1.cend() != nullptr && bigInteger1.cend()->prev != nullptr)
{
node1 = bigInteger1.cend()->prev;
}
if (bigInteger2.cend() != nullptr && bigInteger2.cend()->prev != nullptr)
{
node2 = bigInteger2.cend()->prev;
}
int carry = 0;
int res = 0;
int size = 0;
while (node1 != bigInteger1.cbegin() || node2 != bigInteger2.cbegin())
{
res = (node1 == bigInteger1.cbegin() ? 0 : node1->data) - (node2 == bigInteger2.cbegin() ? 0 : node2->data) - carry;
if (carry == 1)
{
carry = 0;
}
if (res < 0)
{
carry = 1;
res += 10;
}
Node<int>* node = new Node<int>(res, head, curr);
++size;
head->next = node;
curr->prev = node;
curr = node;
node1 = node1 == bigInteger1.cbegin() ? bigInteger1.cbegin() : node1->prev;
node2 = node2 == bigInteger2.cbegin() ? bigInteger2.cbegin() : node2->prev;
}
while (head->next->data == 0)
{
--size;
head = head->next;
}
return BigInteger(Positive, size, head, tail);
}
else if (compare(bigInteger1, bigInteger2) == -1)
{
return opposite(sub(bigInteger2, bigInteger1));
}
else
{
return BigInteger(Positive, 1);
}
}
if (bigInteger1.sign() == Negative && bigInteger2.sign() == Negative)
{
return sub(opposite(bigInteger2), opposite(bigInteger1));
}
if (bigInteger1.sign() == Positive && bigInteger2.sign() == Negative)
{
return add(bigInteger1, opposite(bigInteger2));
}
if (bigInteger1.sign() == Negative && bigInteger2.sign() == Positive)
{
return opposite(add(opposite(bigInteger1), bigInteger2));
}
return BigInteger();
}
BigInteger opposite(BigInteger bigInteger)
{
return BigInteger(!bigInteger.sign(), bigInteger.length(), bigInteger.cbegin(), bigInteger.cend());
}
};
int main()
{
int n = 0;
scanf_s("%d", &n);
getchar();
while (n--)
{
char c = 0;
c = getchar();
getchar();
List<int> list1;
list1.readInteger();
List<int> list2;
list2.readInteger();
BigInteger bigInteger1(list1);
BigInteger bigInteger2(list2);
Calculation calculation;
switch (c)
{
case '+':
calculation.print(calculation.add(bigInteger1, bigInteger2));
break;
case '-':
calculation.print(calculation.sub(bigInteger1, bigInteger2));
break;
default:
break;
}
}
return 0;
}