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

时间:2016-07-17 12:59:24

标签: c++ class linked-list polynomial-math

我有这个关于多项式乘法的代码。 我没有遇到任何错误,我想要的是根据度数(从较低程度到较高程度)对术语进行排序。  如果我在//注释部分的operator *中添加条件,它将被打印太多次。我想知道我是否可以使用m_Polynomial.sort()?如果有,怎么样?如果没有,我可以使用其他什么方法?

由于打印多项式及其乘法结果都是如此,如果可以在打印功能中添加它会很好。

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

最小代码:

 var buildDate:NSDate 
 {
     if let infoPath = NSBundle.mainBundle().pathForResource("Info.plist", ofType: nil),
        let infoAttr = try? NSFileManager.defaultManager().attributesOfItemAtPath(infoPath),
        let infoDate = infoAttr["NSFileCreationDate"] as? NSDate
     { return infoDate }
     return NSDate()
 }

P1.txt

var compileDate:Date
{
    let bundleName = Bundle.main.infoDictionary!["CFBundleName"] as? String ?? "Info.plist"
    if let infoPath = Bundle.main.path(forResource: bundleName, ofType: nil),
       let infoAttr = try? FileManager.default.attributesOfItem(atPath: infoPath),
       let infoDate = infoAttr[FileAttributeKey.creationDate] as? Date
    { return infoDate }
    return Date()
}

P4.txt

#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();
    }

}

输出

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

期望的输出:

P 2
1 4
4 -3

1 个答案:

答案 0 :(得分:3)

您的操作员修改了左操作数,为什么?

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

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

CPolynomial operator*(const CPolynomial& lhs, const CPolynomial& rhs)
{
  CPolynomial result = lhs;
  result *= rhs;
  return result;
}

该错误似乎出现在AddOneTerm中,您进行的比较错误。你的循环会在第一个位置插入新术语(term.deg >= it->deg),但它应该是最后位置,这是真的。

此外,您应在AddOneTerm(term)中使用m_Polynomial.push_back(term)代替ReadFromFile,以确保条款保持正确的顺序。

你也很容易使用迭代器:

        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<Node>结构进行排序,并且可以使用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);
    }
}