多元多项式链表表示及运算(代码可能存在bug)

多元多项式的链式表式见严蔚敏数据结构教材
本文只给出基于这种表示的运算实现,包括加法和乘法
C++代码:(注意代码未经全面严格测试可能存在bug,在此列出代码仅为取得抛砖引玉的作用,笔者可能没有时间精力修改代码中的错误了)

#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <list>
#include "parse.h"
using namespace std;

struct Node
{
    enum class type {sub, leaf} flag;
    size_t order;
    union
    {
        Node* sub_p;
        long long cof;
    };
    Node* next = nullptr;
    Node(size_t order, long long cof) :flag(type::leaf), order(order), cof(cof) {}
    Node(size_t order) :flag(type::sub), order(order), sub_p(nullptr) {}
    Node(Node& copy) :order(copy.order), flag(copy.flag)
    {
        if (flag == type::leaf)
        {
            cof = copy.cof;
        }
        else
        {
            sub_p = nullptr;
        }
    }
};

Node* constructPFromStr(const string& str, size_t level, size_t vary_num)
{
    map<size_t, pair<list<pair<string,string>>, bool>> order_to_sub;  //size_t 项的阶数左string系数,右string子项,bool list<pair<string,string>>里的pair是否为常数
    size_t i = 0;
    pair<token, string> result;
    while (true)
    {
        size_t pre = i;
        result = gettoken(str, i);
        string cof = "";
        if (result.first != token::identifier)
        {
            cof += str.substr(pre, i - pre);
            result = gettoken(str, i);
        }
        else
        {
            cof = "1";
        }

        skip_token(str, i);
        result = gettoken(str, i);
        size_t order = stoul(result.second);
        pre = i;
        bool is_const = true;
        for (size_t j = level + 1; j < vary_num; ++j)
        {
            skip_token(str, i);
            skip_token(str, i);
            result = gettoken(str, i);
            if (result.second != "0")
                is_const = false;
        }
        string sub_p = "";
        sub_p += str.substr(pre, i - pre);

        list<pair<string, string>> sub_p_list;
        sub_p_list.push_back(make_pair(cof, sub_p));
        pair<map<size_t, pair<list<pair<string, string>>, bool>>::iterator, bool> r;
        if (is_const)
        {
            r = order_to_sub.insert(make_pair(order, make_pair(sub_p_list, true)));
        }
        else
        {
            r = order_to_sub.insert(make_pair(order, make_pair(sub_p_list, false)));

        }

        if (r.second == false)
        {
            r.first->second.first.push_back(make_pair(cof, sub_p));
            if (is_const == false)
               r.first->second.second = false;
        }

        result = gettoken(str, i);
        if (result.first == token::end)
            break;
    }

    Node* head = new Node(level);
    Node* run = head;
    for (map<size_t, pair<list<pair<string, string>>, bool>>::reverse_iterator it = order_to_sub.rbegin(); it != order_to_sub.rend(); ++it)
    {
        if (it->second.second == false)
        {
            string _str = "";
            for (list<pair<string, string>>::iterator it2 = it->second.first.begin(); it2 != it->second.first.end(); ++it2)
            {
                if (it2 != it->second.first.begin())
                {
                    _str += "+";
                }
                _str += (it2->first + it2->second);
            }
            Node* s_node = new Node(it->first);
            s_node->sub_p = constructPFromStr(_str, level + 1, vary_num);
            run->next = s_node;
            run = s_node;
        }
        else
        {
            long long cof = 0;
            for (list<pair<string, string>>::iterator it2 = it->second.first.begin(); it2 != it->second.first.end(); ++it2)
            {
                cof += stoll(it2->first);
            }
            Node* leaf = new Node(it->first, cof);
            run->next = leaf;
            run = leaf;
        }
    }
    return head;
}

enum class Token {left_bracket, right_bracket, comma, digit, end};
pair<Token, long long> getNextToken(const string &str, string::size_type &i)
{
    if (i == str.size())
    {
        return { Token::end, 0 };
    }

    if (str[i] == '(')
    {
        ++i;
        return { Token::left_bracket, 0 };
    }
    else if (str[i] == ')')
    {
        ++i;
        return { Token::right_bracket, 0 };
    }
    else if (str[i] == ',')
    {
        ++i;
        return {Token::comma, 0};
    }
    else if (str[i] == '-' || '0' <= str[i] && str[i] <='9')
    {
        string::size_type start = i;
        ++i;
        if (str[start] == '-')
        {
            if (!(i < str.size() && ('1' <= str[i] && str[i] <= '9')))
            {
                cout << "-在上下文中非法!" << endl;
                exit(-1);
            }
            ++i;
        }
        else if (str[start] == '0')
        {
            return { Token::digit, 0 };
        }

        while (i < str.size() && ('0' <= str[i] && str[i] <= '9'))
        {
            ++i;
        }
        return { Token::digit, stoll(str.substr(start, i - start)) };
    }
    else
    {
        cout << "非法字符!" << endl;
        exit(-1);
    }
}

void expectToken(const string& str, string::size_type& i, Token e, pair<Token, long long> &result)
{
    string::size_type j = i;
    result = getNextToken(str, i);
    if (result.first == e)
        return;
    switch (e)
    {
    case Token::left_bracket: { cout << "索引" << j << "处非预期的词法记号,预期为左圆括号" << endl; exit(-1); }
    case Token::right_bracket: { cout << "索引" << j << "处非预期的词法记号,预期为右圆括号" << endl; exit(-1); }
    case Token::comma: { cout << "索引" << j << "处非预期的词法记号,预期为逗号" << endl; exit(-1); }
    case Token::digit: { cout << "索引" << j << "处非预期的词法记号,预期为数字" << endl; exit(-1); }
    case Token::end: { cout << "索引" << j << "处非预期的词法记号,预期为结束" << endl; exit(-1); }
    }
}

void skipToken(const string& str, string::size_type& i)
{
    if (getNextToken(str, i).first == Token::end)
    {
        cout << "ERROR:已没有更多的词法记号,skip失败!" << endl;
        exit(-1);
    }
}   //该函数也可以设计为遇到错误返回false,而不是直接退出
void genPolynomialLegal(const string& str, string::size_type& i, size_t level, shared_ptr<size_t> *pre_leaf_level) //找到了叶子层数就在堆中分配否则为空指针pre_leaf_level
{
    pair<Token, long long> result;
    shared_ptr<size_t> pre_order = nullptr;

    if (level == 0)
    {
        expectToken(str, i, Token::left_bracket, result);
    }

    size_t sub_start = i;
    bool all_is_leaf = true;
    while (true)
    {
        size_t pre = i;
        result = getNextToken(str, i);
        if (result.first == Token::digit || result.first == Token::left_bracket)
        {
            size_t order;
            Token flag = result.first;
            if (result.first == Token::left_bracket)
            {
                pre = i;
                expectToken(str, i, Token::digit, result);
                long long cof = result.second;
                if (cof == 0)
                {
                    cout << "位置:" << pre << "ERROR:系数不能等于0!" << endl;
                    exit(-1);
                }
                expectToken(str, i, Token::comma, result);
                pre = i;
                expectToken(str, i, Token::digit, result);
            }
            if (result.second < 0)
            {
                cout << "位置:" << pre << "ERROR:阶数不能小于0!" << endl;
                exit(-1);
            }
            order = result.second;
            if (pre_order == nullptr)
            {
                pre_order = make_shared<size_t>(order);
            }
            else
            {
                if (order >= *pre_order)
                {
                    cout << "位置:" << pre << "ERROR:该阶数不能小于等于前一个阶数!" << endl;
                    exit(-1);
                }
            }

            if (flag == Token::digit)
            {
                expectToken(str, i, Token::left_bracket, result);
                genPolynomialLegal(str, i, level + 1, pre_leaf_level);
                all_is_leaf = false;
            }
            else
            {
                expectToken(str, i, Token::right_bracket, result);
            }
        }
        else
        {
            cout << "位置:" << pre << "ERROR:非预期的词法记号,预期为左括号或数字!" << endl;
            exit(-1);
        }

        pre = i;
        result = getNextToken(str, i);
        if (result.first == Token::right_bracket)
        {
            if (all_is_leaf)
            {
                if (*pre_leaf_level == nullptr)
                {
                    *pre_leaf_level = make_shared<size_t>(level);
                }
                else
                {
                    if (**pre_leaf_level < level)
                    {
                        **pre_leaf_level = level;
                    }
                }
            }
            return;
        }
        else if (result.first != Token::comma)
        {
            cout << "位置:" << pre << "ERROR:非预期的词法记号,预期为逗号或右括号!" << endl;
            exit(-1);
        }
    }
}

//广义表外围大括号子表阶数从左至右从大到小排列,所有叶子在同一层,阶数不能为负,不允许空表
Node *genPolynomialList(const string& str, string::size_type& i, size_t level)  //该函数假定表示多项式的广义表是合法的,故跳过最开始左括号,i从1开始, level从0开始
{
    Node* head = new Node(level);
    Node* run = head;
    pair<Token, long long> result;
    while (true)
    {
        result = getNextToken(str, i);
        if (result.first == Token::digit)
        {
            size_t order = result.second;
            Node* branch = new Node(order);
            skipToken(str, i);
            branch->sub_p = genPolynomialList(str, i, level + 1);
            run->next = branch;
            run = branch;;
        }
        else  //此时token一定为左括号
        {
            long long cof = getNextToken(str, i).second;
            skipToken(str, i);
            size_t order = getNextToken(str, i).second;
            Node* leaf = new Node(order, cof);
            run->next = leaf;
            run = leaf;
            skipToken(str, i);
        }
        result = getNextToken(str, i);
        if (result.first == Token::right_bracket)
        {
            return head;
        }
    }
}

struct PolynomialSeqExpressNode  //2x^2y^3z^4 阶数234依次从左至右存放在order_list,cof为系数2
{
    long long cof;
    vector<size_t> order_list;
    PolynomialSeqExpressNode(long long c, size_t o) :cof(c), order_list(o, 0) {}
};
//合法的用于初始化多元多项式链表表示的广义表字符串示例:(3((1,2),4((4,5),(2,4))),(9,8)) 
//3(---)表示子多项式,公因子变元阶数为3,括号内是子多项式的广义表表示,是递归定义的(9,8)表示系数为9阶数为8的叶子多项式表示
//同一层各表用,连接
class Polynomial
{
public:
    Polynomial() = default;
    Polynomial(const string& gen_str);
    Polynomial(const string &gen_str, const vector<string> &variable_symbols);
    Polynomial(const Polynomial& copy);
    ~Polynomial();
    bool p_add(const Polynomial &add, Polynomial &result);
    bool p_multiply(const Polynomial& add, Polynomial& result);
    void print();
private:
    Node* add(Node* left_head, Node* right_head);
    Node* multiply(Node* left_head, Node* right_head);
    Node* copy_polynomial(Node* head);
    void delete_polynomial(Node *head);
    Node* convert_leaf_to_sub(Node* leaf, size_t variable_symbols_index);    //把一个leaf的Node节点转化为由一系列分支节点和最底层叶节点链接而成的多项式链表表示,变元索引variable_symbols_index
    void compute_sub_p(Node* add_r, vector<Node*>& multiply_list, size_t m_order, Node* left_head);//从当前值开始往下递增
    shared_ptr<list<PolynomialSeqExpressNode>> convert(Node* head);
    Node* head = nullptr;  //head不是实际头结点而是附加头结点,order域记录变元数目,sub_p域指向实际头结点
    vector<string> variable_symbols; //顺序为zyx逆序排列 链表中的阶由大至小从左至右排列
};

Polynomial::Polynomial(const string& gen_str)  //2x^2y^3z^1+---字符串,每一项固定为顺序xyz,xyz必须都有即便阶数为0,各项之间顺序任意,允许相同项
{
    parse(gen_str, variable_symbols); 
    for (size_t i = 0; i < variable_symbols.size(); ++i)
    {
        for (size_t j = i + 1; j < variable_symbols.size(); ++j)
        {
            if (variable_symbols[i] == variable_symbols[j])
            {
                cout << "ERROR:不能有相同的变元标识符!" << endl;
                exit(-1);
            }
        }
    }
    head = new Node(variable_symbols.size());
    head->sub_p = constructPFromStr(gen_str, 0, variable_symbols.size());
}

shared_ptr<list<PolynomialSeqExpressNode>> Polynomial::convert(Node *_head)  //head不是附加而是实际头结点
{
    shared_ptr<list<PolynomialSeqExpressNode>> _list = make_shared<list<PolynomialSeqExpressNode>>();
    Node* run = _head->next;
    while (run != nullptr)
    {
        if (run->flag == Node::type::sub)
        {
            shared_ptr<list<PolynomialSeqExpressNode>> temp = convert(run->sub_p);
            for (list<PolynomialSeqExpressNode>::iterator it = temp->begin(); it != temp->end(); ++it)
            {
                _list->push_back(*it);
                _list->back().order_list.push_back(run->order);
            }
        }
        else
        {
            PolynomialSeqExpressNode t(run->cof, head->order - _head->order);
            t.order_list.back() = run->order;
            _list->push_back(t);
        }
        run = run->next;
    }
    return _list;
}

void Polynomial::print()
{
    if (head == nullptr)
        cout << "NULL" << endl;
    shared_ptr<list<PolynomialSeqExpressNode>> _list = convert(head->sub_p);
    for (list<PolynomialSeqExpressNode>::iterator it = _list->begin(); it != _list->end(); ++it)
    {
        if (it != _list->begin())
            cout << "+";

        if (it->cof != 1)
           cout << it->cof;
        vector<size_t>& temp = it->order_list;
        size_t index = head->order;
        for (size_t i = 0; i < temp.size(); ++i)
        {
            --index;
            if (temp[i] != 0)
                cout << variable_symbols[index] << "^" << temp[i];
        }
    }
}

bool Polynomial::p_add(const Polynomial& be_add, Polynomial& result)
{
    if (result.head != nullptr)
        return false;
    if (head != nullptr)
    {
        if (be_add.head != nullptr)
        {
            if (variable_symbols.size() != be_add.variable_symbols.size())
                return false;
            for (size_t i = 0; i < variable_symbols.size(); ++i)
            {
                if (variable_symbols[i] != be_add.variable_symbols[i])
                {
                    return false;
                }
            }
            Node *r = add(head->sub_p, be_add.head->sub_p);
            if (r->next != nullptr)
            {
                result.head = new Node(variable_symbols.size());
                result.head->sub_p = r;
            }
        }
        else
        {
            result.head = new Node(variable_symbols.size());
            result.head->sub_p = copy_polynomial(head->sub_p);
        }
        result.variable_symbols = variable_symbols;
    }
    else
    {
        if (be_add.head != nullptr)
        {
            result.head = new Node(be_add.variable_symbols.size());
            result.head->sub_p = copy_polynomial(be_add.head->sub_p);
            result.variable_symbols = be_add.variable_symbols;
        }
    }
    return true;
}

bool Polynomial::p_multiply(const Polynomial& be_multiply, Polynomial& result)
{
    if (result.head != nullptr)
        return false;

    if (head != nullptr)
    {
        if (be_multiply.head != nullptr)
        {
            if (variable_symbols.size() != be_multiply.variable_symbols.size())
                return false;
            for (size_t i = 0; i < variable_symbols.size(); ++i)
            {
                if (variable_symbols[i] != be_multiply.variable_symbols[i])
                {
                    return false;
                }
            }
            result.head = new Node(variable_symbols.size());
            result.head->sub_p = multiply(head->sub_p, be_multiply.head->sub_p);
            result.variable_symbols = variable_symbols;
        }
    }
    return true;
}

Polynomial::~Polynomial()
{
    if (head != nullptr)
    {
        delete_polynomial(head->sub_p);
        delete head;
    }
}
Polynomial::Polynomial(const string& gen_str, const vector<string>& variable_symbols) :variable_symbols(variable_symbols)
{
    if (variable_symbols.empty())
    {
        cout << "ERROR:变元数组不能为空!" << endl;
        exit(-1);
    }
    for (size_t i = 0; i < variable_symbols.size(); ++i)
    {
        if (variable_symbols[i].empty())
        {
            cout << "ERROR:变元标识符为空字符串!" << endl;
            exit(-1);
        }

        if (!(variable_symbols[i][0] == '_' || isalpha(variable_symbols[i][0])))
        {
            cout << "ERROR:变元标识符必须以大小写字符或下划线开头!" << endl;
            exit(-1);
        }

        for (string::size_type j = 1; j < variable_symbols[i].size(); ++j)
        {
            if (!(variable_symbols[i][j] == '_' || isalnum(variable_symbols[i][j])))
            {
                cout << "ERROR:变元标识符除首字符外的其他字符包含非下划线大小写字母或数字的字符!" << endl;
                exit(-1);
            }
        }
    }

    for (size_t i = 0; i < variable_symbols.size(); ++i)
    {
        for (size_t j = i + 1; j < variable_symbols.size(); ++j)
        {
            if (variable_symbols[i] == variable_symbols[j])
            {
                cout << "ERROR:不能有相同的变元标识符!" << endl;
                exit(-1);
            }
        }
    }

    string::size_type i = 0;
    shared_ptr<size_t> pre_leaf_level = nullptr;
    genPolynomialLegal(gen_str, i, 0, &pre_leaf_level);
    if (i != gen_str.size())
    {
        cout << "ERROR:完整的广义表字符串后存在冗余字符!" << endl;
        exit(-1);
    }
    if (*pre_leaf_level + 1 != variable_symbols.size())
    {
        cout << "ERROR:初始化字符串指定的变元个数和vector指示的变元个数不等!" << endl;
        exit(-1);
    }
    i = 1;
    Node *h = genPolynomialList(gen_str, i, 0);
    head = new Node(variable_symbols.size());
    head->sub_p = h;
}

Polynomial::Polynomial(const Polynomial& copy)
{
    if (copy.head != nullptr)
    {
        variable_symbols = copy.variable_symbols;
        head = new Node(variable_symbols.size());
        head->sub_p = copy_polynomial(copy.head->sub_p);
    }
}

Node* Polynomial::convert_leaf_to_sub(Node *leaf, size_t variable_symbols_index)
{
    Node* _head = new Node(variable_symbols_index);
    Node* run = _head;
    while (variable_symbols_index < variable_symbols.size() - 1)
    {
        Node* _new = new Node(0);
        run->next = _new;
        _new->sub_p = new Node(++variable_symbols_index);
        run = _new->sub_p;
    }
    run->next = new Node(0, leaf->cof);
    return _head;
}

void Polynomial::compute_sub_p(Node* add_r, vector<Node*> &multiply_list, size_t m_order, Node* left_head)
{
    if (multiply_list[m_order] == nullptr)
    {
        multiply_list[m_order] = add_r;
    }
    else
    {
        Node* r = nullptr;
        if (multiply_list[m_order]->flag == Node::type::leaf)
        {
            r = convert_leaf_to_sub(multiply_list[m_order], left_head->order + 1);
            delete multiply_list[m_order];
        }
        else
        {
            r = multiply_list[m_order];
        }
        Node* temp = add(r, add_r);
        delete_polynomial(r);
        delete_polynomial(add_r);
        if (temp->next == nullptr)
        {
            delete_polynomial(temp);
            multiply_list[m_order] = nullptr;
        }
        else
        {
            multiply_list[m_order] = temp;
        }
    }
}

Node* Polynomial::multiply(Node* left_head, Node* right_head)
{
    Node* left = left_head->next;
    Node* right = right_head->next;
    size_t _order = left->order + right->order;
    vector<Node*> multiply_list(_order + 1, nullptr);

    while (left != nullptr)
    {
        while (right != nullptr)
        {
            size_t m_order = left->order + right->order;
            Node* add_r = nullptr;
            if (left->flag == Node::type::leaf)
            {
                if (right->flag == Node::type::leaf)
                {
                    if (multiply_list[m_order] == nullptr)
                    {
                        multiply_list[m_order] = new Node(0, left->cof * right->cof);
                    }
                    else
                    {
                        if (multiply_list[m_order]->flag == Node::type::leaf)
                        {
                            long long d = left->cof * right->cof + multiply_list[m_order]->cof;
                            if (d == 0)
                            {
                                delete multiply_list[m_order];
                                multiply_list[m_order] = nullptr;
                            }
                            else
                            {
                                multiply_list[m_order]->cof = d;
                            }
                        }
                        else
                        {
                            Node *l = new Node(0, left->cof * right->cof);
                            Node* temp = convert_leaf_to_sub(l, left_head->order + 1);
                            delete l;
                            add_r = add(temp, multiply_list[m_order]);
                            delete_polynomial(temp);
                            delete_polynomial(multiply_list[m_order]);
                            if (add_r->next == 0)
                            {
                                delete_polynomial(add_r);
                                multiply_list[m_order] = nullptr;
                            }
                            else
                            {
                                multiply_list[m_order] = add_r;
                            }
                        }
                    }
                    right = right->next;
                    continue;
                }
                else
                {
                    Node* temp = convert_leaf_to_sub(left, left_head->order + 1);
                    add_r = multiply(temp, right->sub_p);
                    delete_polynomial(temp);
                }
            }
            else
            {
                if (right->flag == Node::type::leaf)
                {
                    Node* temp = convert_leaf_to_sub(right, right_head->order + 1);
                    add_r = multiply(temp, left->sub_p);
                    delete_polynomial(temp);
 
                }
                else
                {
                    add_r = multiply(left->sub_p, right->sub_p);                  
                }
            }
            compute_sub_p(add_r, multiply_list, m_order, left_head);
            right = right->next;
        }
        left = left->next;
    }

    Node* multiply_result_head = new Node(*left_head);
    Node* run_on_result = multiply_result_head;
    
    for (size_t i = multiply_list.size() - 1; ; --i)
    {
        if (multiply_list[i] == nullptr)
        {
            if (i == 0)
                break;
            continue;
        }

        Node* n = nullptr;
        if (multiply_list[i]->flag == Node::type::sub)
        {
            n = new Node(i);
            n->sub_p = multiply_list[i];
        }
        else
        {
            n = multiply_list[i];
            n->order = i;
        }
        run_on_result->next = n;
        run_on_result = n;

        if (i == 0)
            break;
    }
    return multiply_result_head;
}

Node* Polynomial::add(Node *left_head, Node* right_head)
{
    Node* add_result_head = new Node(*left_head);
    Node* run_on_result = add_result_head;
    Node* left = left_head->next;
    Node* right = right_head->next;
    Node* _temp = nullptr;
    while (left != nullptr && right != nullptr)
    {       
        if (left->order == right->order)
        {
            if (left->flag == Node::type::leaf)
            {
                if (right->flag == Node::type::leaf)
                {
                    if (left->cof + right->cof == 0)
                    {
                        left = left->next;
                        right = right->next;
                        continue;
                    }
                    _temp = new Node(left->order, left->cof + right->cof);
                }
                else
                {
                    Node* temp = convert_leaf_to_sub(left, left_head->order + 1);  
                    Node* add_r = add(temp, right->sub_p);
                    delete_polynomial(temp);
                    if (add_r->next == nullptr)
                    {
                        left = left->next;
                        right = right->next;
                        continue;
                    }
                    _temp = new Node(right->order);
                    _temp->sub_p = add_r;
                }
            }
            else
            {
                Node* add_r = nullptr;
                if (right->flag == Node::type::leaf)
                {
                    Node* temp = convert_leaf_to_sub(right, left_head->order + 1);  
                    add_r = add(temp, left->sub_p);
                    delete_polynomial(temp);
                    if (add_r->next == nullptr)
                    {
                        left = left->next;
                        right = right->next;
                        continue;
                    }
                }
                else
                {
                    add_r = add(left->sub_p, right->sub_p);
                    if (add_r->next == nullptr)
                    {
                        left = left->next;
                        right = right->next;
                        continue;
                    }
                }
                _temp = new Node(left->order);
                _temp->sub_p = add_r;
            }
            left = left->next;
            right = right->next;
        }
        else if (left->order < right->order)
        {
            if (left->flag == Node::type::leaf)
            {
                _temp = new Node(left->order, left->cof);
            }
            else
            {
                Node* copy = copy_polynomial(left->sub_p);
                _temp = new Node(left->order);
                _temp->sub_p = copy;
            }
            right = right->next;
        }
        else
        {
            if (right->flag == Node::type::leaf)
            {
                _temp = new Node(right->order, right->cof);
            }
            else
            {
                Node* copy = copy_polynomial(right->sub_p);
                _temp = new Node(right->order);
                _temp->sub_p = copy;
            }
            left = left->next;
        }
        run_on_result->next = _temp;
        run_on_result = _temp;
    }

    while (left != nullptr)
    {
        if (left->flag == Node::type::leaf)
        {
            _temp = new Node(left->order, left->cof);
        }
        else
        {
            Node* copy = copy_polynomial(left->sub_p);
            _temp = new Node(left->order);
            _temp->sub_p = copy;
        }
        run_on_result->next = _temp;
        run_on_result = _temp;
        left = left->next;
    }

    while (right != nullptr)
    {
        if (right->flag == Node::type::leaf)
        {
            _temp = new Node(right->order, right->cof);
        }
        else
        {
            Node* copy = copy_polynomial(right->sub_p);
            _temp = new Node(right->order);
            _temp->sub_p = copy;
        }
        run_on_result->next = _temp;
        run_on_result = _temp;
        right = right->next;
    }
    return add_result_head;
}

void Polynomial::delete_polynomial(Node* head)
{
    while (head->next != nullptr)
    {
        Node* run = head->next;
        head->next = run->next;
        if (run->flag == Node::type::sub)
        {
            delete_polynomial(run->sub_p);
        }
        delete run;
    }
    delete head;
}

Node* Polynomial::copy_polynomial(Node* head)
{
    Node* _head = new Node(*head);
    Node* run = head->next;
    Node* copy_run = _head;
    while (run != nullptr)
    {
        Node* copy_result = new Node(*run);
        copy_run->next = copy_result;
        copy_run = copy_result;
        if (run->flag == Node::type::sub)
        {
            copy_result = copy_polynomial(run->sub_p);
            copy_run->sub_p = copy_result;
        }
        run = run->next;
    }
    return _head;
}

int main()
{
    vector<string> vs = {"z", "y", "x"};
    string test_str = "(3(4((4,5),(2,4)),(1,2)),(9,2))";
    string test_str_2 = "z^2y^2x^2+z^2y^1x^2+z^2y^1x^1+2z^1y^3x^2+3z^1y^3x^1+14z^2y^0x^0+2z^1y^0x^0";

    Polynomial obj1(test_str, vs);
    Polynomial obj2(test_str_2);
    Polynomial copy(obj1);
    Polynomial result1;
    Polynomial result2;
    obj1.p_add(obj2, result1);
    obj1.p_multiply(obj2, result2);
    cout << "加法结果" << endl;
    result1.print();
    cout << endl;
    cout << "乘法结果" << endl;
    result2.print();
    cout << endl;
    cout << "拷贝结果" << endl;
    copy.print();   
    cout << endl;
    return 0;
}
parse.h头文件的内容

```cpp
#pragma once
#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;

enum class token {plus, digit, identifier, pow, end};
pair<token, string> gettoken(const string& str, string::size_type& i)
{
    if (i == str.size())
    {
        return { token::end, ""};
    }

    if (str[i] == '+')
    {
        ++i;
        return { token::plus, "" };
    }

    if (str[i] == '^')
    {
        ++i;
        return { token::pow, "" };
    }

    if (str[i] == '_' || isalpha(str[i]))
    {
        size_t start = i;
        do
        {
            ++i;
        } while (i < str.size() && (str[i] == '_' || isalnum(str[i])));
        return { token::identifier, str.substr(start, i - start) };
    }

    if (str[i] == '-' || '0' <= str[i] && str[i] <= '9')
    {
        size_t start = i;
        ++i;
        if (str[start] == '-')
        {
            if (!(i < str.size() && ('1' <= str[i] && str[i] <= '9')))
            {
                cout << "-在上下文中非法!" << endl;
                exit(-1);
            }
            ++i;
        }
        else if (str[start] == '0')
        {
            return { token::digit, "0" };
        }

        while (i < str.size() && ('0' <= str[i] && str[i] <= '9'))
        {
            ++i;
        }
        return { token::digit, str.substr(start, i - start) };
    }
    cout << "非法字符!" << endl;
    exit(-1);
}

void expect(const string& str, string::size_type& i, token e, pair<token, string>& result)
{
    string::size_type j = i;
    result = gettoken(str, i);
    if (result.first == e)
        return;
    switch (e)
    {
    case token::plus: { cout << "索引" << j << "处非预期的词法记号,预期为加号" << endl; exit(-1); }
    case token::digit: { cout << "索引" << j << "处非预期的词法记号,预期为数字" << endl; exit(-1); }
    case token::identifier: { cout << "索引" << j << "处非预期的词法记号,预期为标识符" << endl; exit(-1); }
    case token::pow: { cout << "索引" << j << "处非预期的词法记号,预期为幂" << endl; exit(-1); }
    case token::end: { cout << "索引" << j << "处非预期的词法记号,预期为结束" << endl; exit(-1); }
    }
}

void skip_token(const string& str, string::size_type& i)
{
    if (gettoken(str, i).first == token::end)
    {
        cout << "ERROR:已没有更多的词法记号,skip失败!" << endl;
        exit(-1);
    }
}

void parse(const string& str, vector<string> & variable_symbols) //variable_symbols初始为空
{
    size_t i = 0;
    pair<token, string> result;

    while (true)
    {
        size_t pre = i;
        result = gettoken(str, i);
        if (result.first == token::digit)
        {
            if (result.second == "0")
            {
                cout << "位置:" << pre << "ERROR:系数不能为0" << endl;
                exit(-1);
            }
            pre = i;
            expect(str, i, token::identifier, result);
        }
        else if (result.first != token::identifier)
        {
            cout << "位置:" << pre << "ERROR:非预期的词法记号预期为数字或标识符" << endl;
            exit(-1);
        }

        bool has_get = !variable_symbols.empty();
        size_t index = 0;
        while (true)
        {
            if (has_get == false)
            {
                variable_symbols.push_back(result.second);
            }
            else
            {
                if (index >= variable_symbols.size())
                {
                    cout << "位置:" << pre << "ERROR:不同的项的变量标识符数目不匹配,出错的标识符为"<< result.second << endl;
                    exit(-1);
                }
                if (variable_symbols[index++] != result.second)
                {
                    cout << "位置:" << pre << "ERROR:不匹配的变量标识符"<< result.second << endl;
                    exit(-1);
                }
            }
            expect(str, i, token::pow, result);
            pre = i;
            expect(str, i, token::digit, result);
            if (result.second[0] == '-')
            {
                cout << "位置:" << pre << "ERROR:变量的幂不能为负值" << endl;
                exit(-1);
            }
            pre = i;
            result = gettoken(str, i);
            if (result.first == token::end)
            {
                if (has_get && index < variable_symbols.size())
                {
                    cout << "ERROR:最后一项变量标识符数目不匹配" << endl;
                    exit(-1);
                }
                return;
            }

            if (result.first == token::plus)
            {
                if (has_get && index < variable_symbols.size())
                {
                    cout << "位置:" << pre << "ERROR:加号前的项的变量标识符数目不匹配" << endl;
                    exit(-1);
                }
                break;
            }

            if (result.first != token::identifier)
            {
                cout << "位置:" << pre << "ERROR:非预期的词法记号预期为结束或加号或标识符" << endl;
                exit(-1);
            }
        }
    }
}

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多项式可以用链表表示,每个节点表示多项式的一项,包含三个属性:系数、指数、指向下一个节点的指针。链表的头节点表示多项式的开头。 多项式的加法可以通过遍历两个多项式链表,将指数相同的项的系数相加,新建一个节点保存结果,最后将剩余项直接拼接到结果链表的尾部。 多项式的乘法也可以通过遍历两个多项式链表,将每一项相乘,得到新的一项,将所有新的一项相加即为结果。具体来说,我们可以对第一个多项式的每一项,在第二个多项式上遍历,将指数相加得到新的指数,将系数相乘得到新的系数,将新的一项插入到结果链表中。 需要注意的是,对于乘法,要在插入新项之前检查结果链表中是否已经有相同指数的项,如果有,则将系数相加,否则直接插入新项。 以下是一个简单的多项式链表的定义和加法、乘法操作的实现代码C++): ```c++ struct PolyNode { int coef; // 系数 int exp; // 指数 PolyNode* next; // 下一项节点指针 }; PolyNode* addPoly(PolyNode* p1, PolyNode* p2) { PolyNode* head = new PolyNode(); // 结果链表头节点 PolyNode* tail = head; // 结果链表尾指针 while (p1 && p2) { if (p1->exp == p2->exp) { // 指数相同,系数相加 int coef = p1->coef + p2->coef; if (coef != 0) { // 系数不为0才添加新项 PolyNode* node = new PolyNode(); node->coef = coef; node->exp = p1->exp; tail->next = node; tail = node; } p1 = p1->next; p2 = p2->next; } else if (p1->exp > p2->exp) { // p1的指数大,将p1的项添加到结果中 PolyNode* node = new PolyNode(); node->coef = p1->coef; node->exp = p1->exp; tail->next = node; tail = node; p1 = p1->next; } else { // p2的指数大,将p2的项添加到结果中 PolyNode* node = new PolyNode(); node->coef = p2->coef; node->exp = p2->exp; tail->next = node; tail = node; p2 = p2->next; } } // 将剩余的项添加到结果中 while (p1) { PolyNode* node = new PolyNode(); node->coef = p1->coef; node->exp = p1->exp; tail->next = node; tail = node; p1 = p1->next; } while (p2) { PolyNode* node = new PolyNode(); node->coef = p2->coef; node->exp = p2->exp; tail->next = node; tail = node; p2 = p2->next; } // 删除头节点 PolyNode* temp = head; head = head->next; delete temp; return head; } PolyNode* multiplyPoly(PolyNode* p1, PolyNode* p2) { PolyNode* head = new PolyNode(); // 结果链表头节点 PolyNode* tail = head; // 结果链表尾指针 while (p1) { PolyNode* p = p2; while (p) { int coef = p1->coef * p->coef; int exp = p1->exp + p->exp; // 在结果链表中查找是否有指数相同的项 PolyNode* node = head; while (node && node->exp != exp) { node = node->next; } if (node) { // 已有相同指数的项,将系数相加 node->coef += coef; if (node->coef == 0) { // 系数为0,删除该项 PolyNode* temp = node; node = node->next; delete temp; } } else { // 没有相同指数的项,直接添加新项到结果链表 node = new PolyNode(); node->coef = coef; node->exp = exp; tail->next = node; tail = node; } p = p->next; } p1 = p1->next; } // 删除头节点 PolyNode* temp = head; head = head->next; delete temp; return head; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值