基于度数对多项式项进行排序

Posted

技术标签:

【中文标题】基于度数对多项式项进行排序【英文标题】:Sorting polynomial terms based on degrees 【发布时间】:2016-07-17 12:59:24 【问题描述】:

我有这个关于多项式乘法的代码。 我没有遇到错误,只是我想要的是根据学位(从低学位到更高学位)对术语进行排序。 如果我在 //commented 部分的 operator* 中添加条件,它将被打印太多次。我想知道我是否可以使用 m_Polynomial.sort()?如果是怎么办?如果没有,我还可以使用哪些其他方法?

因为它既可以用于打印多项式,也可以用于它们的乘法结果,如果可以将其添加到打印函数中就更好了。

如果可以将多项式的打印样式更改为所需格式(添加相同次数项的系数)

最小代码:

#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <vector>
using namespace std;


typedef struct Node

    double  cof;      // coefficient 
    int     deg;      // degree
 Node;

class CPolynomial

public:
    CPolynomial();
    CPolynomial(const string& file);
    ~CPolynomial();
    CPolynomial operator*(const CPolynomial &right);
    CPolynomial& operator=(const CPolynomial &right);
    void Print() const;

private:
    void ReadFromFile(string file);

private:
    list<Node> m_Polynomial;
;



int main()

    CPolynomial p1("P3.txt");
    CPolynomial p2("P4.txt");
    CPolynomial p3;
    p1.Print();
    p2.Print();

    p3 = p1*p2;
    p3.Print();

    system("pause");
    return 0;


CPolynomial::CPolynomial()

    Node term;
    term.cof = 0;
    term.deg = 0;
    m_Polynomial.push_back(term);


CPolynomial::~CPolynomial()

    m_Polynomial.clear();


CPolynomial::CPolynomial(const string& file)

    ReadFromFile(file);


CPolynomial CPolynomial:: operator*(const CPolynomial &right)

    CPolynomial result;
    result.m_Polynomial = m_Polynomial;

    for (list<Node>::iterator itr = result.m_Polynomial.begin(); itr != result.m_Polynomial.end(); ++itr)
    
        itr->cof = 0;
        itr->deg = 0;
    

    Node term;
    Node termR;
    Node temp;

    for (list<Node>::const_iterator it = m_Polynomial.begin(); it != m_Polynomial.end(); ++it)
    
        for (list<Node>::const_iterator itR = right.m_Polynomial.begin(); itR != right.m_Polynomial.end(); ++itR)
        
            term = *it;
            termR = *itR;

            temp.cof = termR.cof* term.cof;
            temp.deg = termR.deg + term.deg;

            for (list<Node>::iterator itr = result.m_Polynomial.begin(); itr != result.m_Polynomial.end(); ++itr)
            
                if (temp.deg == itr->deg)
                
                    temp.cof += itr->cof;
                    itr->cof = 0;
                
            // if(temp.deg < it->deg)
            //result.m_Polynomial.insert(it, temp);
            
            result.m_Polynomial.push_back(temp);
        
    
    return result;


CPolynomial& CPolynomial:: operator=(const CPolynomial &right)


    this->m_Polynomial = right.m_Polynomial;
    return *this;


void CPolynomial::Print() const

    list<Node>::const_iterator it;

    for (it = m_Polynomial.begin(); it != m_Polynomial.end(); it++)
    
        if (it->cof == 0)
        
            ;
        
        else
        
            if (it->cof > 0)
            
                if (it != m_Polynomial.begin()) // if 'it' is not the first term, '+' is not necessary
                    cout << "+";
            
            cout << it->cof;
            if (it->deg != 0)
                cout << "x^" << it->deg;
        
    
    cout << endl;


void CPolynomial::ReadFromFile(string file)

    Node term;
    fstream MyFile;
    string p;
    int num;

    MyFile.open(file);

    if (!MyFile.is_open())
    
        cerr << "Unable to open input file" << endl;
        exit(EXIT_FAILURE);
    
    else
    
        MyFile >> p >> num;

        std::list<Node>::iterator it = m_Polynomial.begin();

        for (int i = 0; i < num; i++)
        
            MyFile >> term.deg >> term.cof;

            m_Polynomial.push_back(term);
        
        MyFile.close();
    


P1.txt

P 8
0 2
5 -3
12 5
2 6
5 7
3 -4
2 9
2 2

P4.txt

P 2
1 4
4 -3

输出

2-3^5+5x^12+6x^2+7x^5-4x^3+9x^2+2x^2         (P1)
4x^1-3x^4                                    (P2)
8x^1+20x^13-15x^16_12x^9-22x^4+12x^7+68x^3    (P1*P2)

想要的输出:

2+17x^2-4x^3+4x^5+5x^12
4x^1-3x^4 
8x^1+68x^3-22x^4+12x^7_12x^9+20x^13-15x^16

【问题讨论】:

添加语言标签 为什么你的operator**this 上运行?这意味着如果你说a * b,那么它会修改a 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括期望的行为、特定问题或错误以及重现它所需的最短代码在问题本身。没有明确问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example。 【参考方案1】:

你的操作符修改了它的左操作数,为什么?

如果你说p3 = p1 * p2;那么修改p1是错误的,你应该返回一个具有新值的新对象,而不是改变操作数。

一种解决方案是提供operator*= 作为改变其左操作数的成员函数,然后将operator* 定义为非成员函数:

CPolynomial operator*(const CPolynomial& lhs, const CPolynomial& rhs)

  CPolynomial result = lhs;
  result *= rhs;
  return result;

错误似乎在AddOneTerm 中,您在其中进行了错误的比较。您的循环将在 first 位置插入新术语,(term.deg &gt;= it-&gt;deg) 但它应该是 last 位置,这是正确的。

您还应该在ReadFromFile 中使用AddOneTerm(term) 而不是m_Polynomial.push_back(term),以确保条款保持正确的顺序。

您对迭代器的使用也很混乱:

        std::list<Node>::iterator next_it;
        next_it = ++it;

现在next_itit 都增加了,所以它们都是下一个任期。为什么?

我建议更简单的:

void CPolynomial::AddOneTerm(Node term)

    auto it = m_Polynomial.begin();
    while (it != m_Polynomial.end() && it->deg < term.deg)
    
        ++it;
    

    if (it != m_Polynomial.end() && term.deg == it->deg)
    
        it->cof += term.cof;
    
    else
    
        m_Polynomial.insert(it, term);
    

您还可以为Node 对象定义比较运算符:

bool operator<(const Node& l, const Node& r)

    return l.deg < r.deg;

现在您可以轻松地对您的list&lt;Node&gt; 结构进行排序,并且您可以使用lower_boundAddOneTerm 中找到正确的位置:

void CPolynomial::AddOneTerm(Node term)

    auto it = std::lower_bound(m_Polynomial.begin(), m_Polynomial.end(), term);

    if (it != m_Polynomial.end() && term.deg == it->deg)
    
        it->cof += term.cof;
    
    else
    
        m_Polynomial.insert(it, term);
    

【讨论】:

所有 cof 和度数都正确最终结果不正确:6x^1-9x^4 很抱歉我尝试了多少我无法在评论中以代码格式编写 所以不要把它放在评论中,编辑你的问题。您还应该显示所有相关代码,而不仅仅是一个函数。请阅读本网站的文档,了解如何提出问题,以及如何提供一个最小、完整、可验证的示例。 已编辑。只是代码太长,我添加了相关功能。考虑他们为其他功能正确行事 “只是代码太长”这就是为什么网站文档说要创建一个最小完整的可验证示例。你读过吗? 为什么没人帮我?:(

以上是关于基于度数对多项式项进行排序的主要内容,如果未能解决你的问题,请参考以下文章

WinForm基于插件开发实现多项配置存储

使用 Python 示例对多项朴素贝叶斯分类器进行分类

GraphQL 查询中的多项查找

js 归并排序

当人们拥有多项工作时,使用人员、职位和团队对组织进行建模的最佳方法是啥? [关闭]

基于MATLAB的多项式数据拟合方法研究-毕业论文