C++链表大数加减

用链表实现大整数相加减(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;
}
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值