C++ 多项式计算器

exe程序

点此下载

功能

输入多项式

  为了方便起见,将多项式表示成数对的形式。如 x2+1 可表示成(1,2)(1,0), 5x64x3+2 可表示成 (5,6)(-4,3)(2,0)。当然,你的输入必须得合法,否则,我的程序会告诉你输入错误。不过为了让软件记住这个多项式,你可以输入p=(1,2)(1,0),q=(5,6)(4,3)(2,0)的形式,那么以后你就可以用p、q表示多项式了。当你想进行加减法运算时,只需要输⼊入p、q就可以了。

输出多项式

  输出时,我会以 x53x3+5 之类的样子显示结果的

保存多项式

  我的程序会询问你是否保存此多项式,如果你想保存,只需要输入多项式的名字就可以了。

多项式加减乘求导求值判等

全局可按Esc键返回主菜单

开发环境

  1. Windows 10 + Visual Studio 2017 Cummunity;

异常处理

  1. 读取输入不允许输入空格;
  2. 多项式只能输入100组以内的数对, 且必须按(float,int)输入(+1.0,+1)(-0.1,-1)(.1,1)合法, (-.1,-1)(+.1,1)(1.1.1,1)(1.0,0.1)(a,b)不合法;
  3. 多项式命名只能包含字母数字;
  4. 菜单选择异常自动重来;
  5. 文件简易检查;
  6. 多项式名称限定10位以内;
  7. 多项式名称检查, 可带空格;

设计

  1. 单例模式;
  2. 结构:
    结构

特点

  1. 多项式名称限定10位以内;
  2. 等号对齐显示储存多项式;
  3. 在操作上方显示记录, 方便操作;
  4. 为Display Record加入Delete a Polynominal子功能;
  5. 改善直接Enter空输入的情形;
  6. 修复了保存结果多项式输入名字时有空格引起不良反应的BUG;
  7. 主菜单用getch()提示错误指令对双字节键的优化, 避免一闪而过
else if (ch == 0x00 || ch == 0xE0) {
    cout << "\nError Dictate!";
    _getch();
    _getch();
}

随时返回主菜单

bool inputEsc(string & get) {
    int ch;
    while (1) {
        ch = _getch();
        if (ch == 0x00 || ch == 0XE0)   //if extended key
            _getch();   //gets scan code
        else if (ch == 27)
            return false;
        else if (ch == 8 && get.length() > 0) {
            cout << "\b \b";    // backspace, 光标回退一格
            get = get.substr(0, get.length() - 1);
        }
        else if (ch == '\r') {
            cout << "\n";
            if (get.length() == 0)
                continue;
            else
                break;
        }
        else if(ch >= 32 && ch <= 126) {    //可打印字符
            cout << static_cast<char> (ch);
            get += ch;
        }
    }
    return true;
}

基本思路

  1. 采用conio.h的非缓冲输入getch()函数 (VS为_getch()), 可打印的实时打印并记录到string上, Backspace光标左移打印空格再光标左移, 模拟缓冲输入效果, Esc返回非, Enter结束输入, 其他忽略;

细节

  1. 键盘一些控制键如上下左右键的键值是双字节的, 而getch()只能读取单字节, 读取扩展字符必须进行两次调用, 第一次返回该键的扩展的字符(0xE0 或 0x00), 第二个调用返回的实际的键代码;
  2. 一开始误用char ch, ch=getch(), 这样无法判断0xE0 或 0x00, 应用int ch;
  3. 对于Backspace, 应判断string的长度是否不是0, 若不判断, 将导致界面越界回退;
  4. 对于Enter, 应判断string的长度是否是0, 若不判断, 将导致输入可能为空;

缺陷

  1. 输入时无法通过Ctrl+V粘贴数据, 但可通过快速编辑的右键粘贴;
  2. 输入时左右键失效;

心得

  1. 拷贝构造函数参数必须为 const 类型的引用
  2. sscanf 的用法
  3. getline(cin,string)要包含
  4. 文件流 peek()指针位置停留在前, eof()指针位置同步
  5. c++11for(auto x: mapName)x.first x.second 的遍历 ; 元素插入 insert(make_pair(key,value))
  6. 字符串转数字
//C风格
const char *in = input.c_str();
for (int i = 0; i < count; i++) {
    int exp;
    float coef;
    sscanf_s(in, "%*c%f%*c%d%*c", &coef, &exp);
    addTerm(exp, coef);
}
//C++风格
stringstream in(input);
for (int i = 0; i < count; i++) {
    int exp;
    float coef;
    char ch;
    in >> ch >> coef >> ch >> exp >> ch;
    addTerm(exp, coef);
}

源码

main.cpp

#include"Control.h"
#include<stdlib.h>
#include<conio.h>
#include<iostream>
using namespace std;
int main() {
    read();
    while (1) {
        system("cls");
        printMenu();
        int ch;
        ch = _getch();
        if (ch == '1')
            save();
        else if (ch == '2')
            operate('+');
        else if (ch == '3')
            operate('-');
        else if (ch == '4')
            operate('*');
        else if (ch == '5')
            dif();
        else if (ch == '6')
            evl();
        else if (ch == '7')
            operate('=');
        else if (ch == '8')
            dsp();
        else if (ch == '9')
            res();
        else if (ch == '0')
            break;
        else if (ch == 27) {
            cout << "\n\nMain Menu Already!";
            _getch();
        }
        else if (ch == 0x00 || ch == 0xE0) {
            cout << "\nError Dictate!";
            _getch();
            _getch();
        }
        else if (ch == 'a' || ch == 'A') {
            cout << "\n\n> About\n\nEmail: 870949712@qq.com\n\nCopyright 2017 Zhang Jiqi,SYSU\nAll rights reserved.";
            _getch();
        }
        else {
            cout << "\nError Dictate!";
            _getch();
        }
    }
    write();
    return 0;
}

Control.h

#pragma once
#include"Calculator.h"
#include<iostream>
#include<conio.h>
#include<string>
#include<stdlib.h>
using namespace std;

Calculator *cal = Calculator::getInstance();
void printMenu() {
    system("cls");
    cout << "> Polynomial Calculator\n\n"
        << " 1 --- Save Polynominal\n"
        << " 2 ----------- Addition\n"
        << " 3 -------- Subtraction\n"
        << " 4 ----- Multiplication\n"
        << " 5 ---- Differentiation\n"
        << " 6 --------- Evaluation\n"
        << " 7 ----------- Judgment\n"
        << " 8 ----- Display Record\n"
        << " 9 -------------- Reset\n"
        << " 0 --------------- Exit\n\n"
        << "Instruction:";
}
//判断浮点数输入是否合法
bool floatValid(const string Input) {
    string input = Input;
    int leftp = -1;
    if (input[leftp + 1] != '+'&&input[leftp + 1] != '-'&&input[leftp + 1] != '.' && (input[leftp + 1]>'9' || input[leftp + 1]<'0'))
        return false;
    if (input[leftp + 1] == '+' || input[leftp + 1] == '-' || input[leftp + 1] == '.')
        if (input[leftp + 2]>'9' || input[leftp + 2]<'0')
            return false;
    int point = 0;
    if (input[leftp + 1] == '.')
        point = 1;
    size_t i;
    for (i = leftp + 2; i<input.length(); i++) {
        if (input[i] == '.') {
            point++;
            if (point>1)
                return false;
            if (input[i + 1]>'9' || input[i + 1]<'0')
                return false;
        }
        else if (input[i]>'9' || input[i]<'0')
            return false;
    }
    return true;
}
//判断多项式输入是否合法
bool polyIsValid(const string input) {
    if (input[0] != '(')
        return false;
    int leftp = 0, flag = 0, count = 0;
    while (1) {
        // (~,
        if (input[leftp + 1] != '+'&&input[leftp + 1] != '-'&&input[leftp + 1] != '.' && (input[leftp + 1]>'9' || input[leftp + 1]<'0'))
            return false;
        if (input[leftp + 1] == '+' || input[leftp + 1] == '-' || input[leftp + 1] == '.')
            if (input[leftp + 2]>'9' || input[leftp + 2]<'0')
                return false;
        int point = 0;
        if (input[leftp + 1] == '.')
            point = 1;
        size_t i;
        for (i = leftp + 2; i<input.find(',', leftp + 1); i++) {
            if (input[i] == '.') {
                point++;
                if (point>1)
                    return false;
                if (input[i + 1]>'9' || input[i + 1]<'0')
                    return false;
            }
            else if (input[i]>'9' || input[i]<'0')
                return false;
        }
        // ,~)
        if (input[i + 1] != '+'&&input[i + 1] != '-' && (input[i + 1]>'9' || input[i + 1]<'0'))
            return false;
        if (input[i + 1] == '+' || input[i + 1] == '-')
            if (input[i + 2]>'9' || input[i + 2]<'0')
                return false;
        for (i = i + 2; i<input.find(')', leftp + 1); i++)
            if (input[i]>'9' || input[i]<'0')
                return false;
        if (i + 1 == input.length())
            return true;
        if (input[i + 1] != '(')
            return false;
        leftp = i + 1;
        count++;
        if (count > 100)
            return false;
    }
}
//判断名称输入是否合法
bool nameIsValid(const string input) {
    if (input.length() > 10)
        return false;
    for (size_t i = 0; i < input.length(); i++)
        if (!(input[i] >= 'a'&&input[i] <= 'z') && !(input[i] >= 'A'&&input[i] <= 'Z') && !(input[i] >= '0'&&input[i] <= '9'))
            return false;
    return true;
}
//判断名称是否已存在
bool nameExist(const string input) {
    return(cal->nameExist(input));
}
//实现随时返回输入字符串
bool inputEsc(string & get) {
    int ch;
    while (1) {
        ch = _getch();
        if (ch == 0x00 || ch == 0XE0)   //if extended key
            _getch();   //gets scan code
        else if (ch == 27)
            return false;
        else if (ch == 8 && get.length() > 0) {
            cout << "\b \b";    // backspace, 光标回退一格
            get = get.substr(0, get.length() - 1);
        }
        else if (ch == '\r') {
            cout << "\n";
            if (get.length() == 0)
                continue;
            else
                break;
        }
        else if(ch >= 32 && ch <= 126) {    //可打印字符
            cout << static_cast<char> (ch);
            get += ch;
        }
    }
    return true;
}
//菜单功能
void save() {
    while (1) {
        system("cls");
        cout << "> Polynomial Calculator > Save a polynominal\n\n"
            << "e.g. p=(1,2)(1,0)\n\n";
        int flag = 0;
        string input;
        if (!inputEsc(input))
            break;
        if (input.find(' ') != -1)
            flag = 1;
        else {
            size_t count = 0;
            for (size_t i = 1; i < input.length(); i++) //i begin with 1
                if (input[i] == '=')
                    count++;
            if (count != 1)
                flag = 1;
        }
        string name, poly;
        if (!flag) {
            name = input.substr(0, input.find('='));
            poly = input.substr(input.find('=') + 1);
            if (!polyIsValid(poly) || !nameIsValid(name))
                flag = 1;
            else if (nameExist(name))
                flag = 2;
        }
        if (flag == 0) {
            cal->current = poly;
            cal->addPoly(name, cal->current);
            cout << endl << name << " = ";
            cal->printPoly(name);
            cout << " successfully saved!\n\n"
                << "Press any key to return";
            _getch();
            break;
        }
        if (flag == 1)
            cout << "\nSyntax Error!\n";
        else if (flag == 2)
            cout << "\nExistent Name!\n";
        cout << "\nPress Esc to return, other keys to continue";
        if (_getch() == 27)
            break;
    }
}
//识别是具体多项式或是名称,并进行合法性判断
int judge(const string target) {
    int flag = 0;
    if (target.find(' ') != -1)
        flag = 1;
    else {
        if (target[0] == '(') {
            if (!polyIsValid(target))
                flag = 1;
            else
                flag = 2;
        }
        else {
            if (!nameIsValid(target))
                flag = 1;
            else
                flag = 3;
        }
        if (flag == 3 && !nameExist(target))
            flag = 4;
        if (flag == 1)
            cout << "\nSyntax Error!\n";
        else if (flag == 4)
            cout << "\nNon-Existent Name!\n";
    }
    return flag;
}
//左右多项式的输入
int leftright() {
    string left, right;
    cout << "Input a concrete polynominal or its name if only existed.\n\n";
    cout << "Lvalue:\n";
    if (!inputEsc(left))
        return 0;
    int flag = judge(left);
    if (flag == 1 || flag == 4) {
        cout << "\nPress Esc to return, other keys to continue";
        if (_getch() == 27)
            return 0;
        return 1;
    }
    else if (flag == 2)
        cal->left = left;
    else if (flag == 3)
        cal->left = cal->getPoly(left);
    cout << "\nRvalue:\n";
    if (!inputEsc(right))
        return 0;
    flag = judge(right);
    if (flag == 1 || flag == 4) {
        cout << "\nPress Esc to return, other keys to continue";
        if (_getch() == 27)
            return 0;
        return 1;
    }
    else if (flag == 2)
        cal->right = right;
    else if (flag == 3)
        cal->right = cal->getPoly(right);
    return 2;
}
//保存结果多项式
int saveResult() {
    cout << "\nInput 1 to return, 2 to save the result, other to continue\n";
    string ch;
    if (!inputEsc(ch))
        return 0;
    if (ch == "1")
        return 0;
    if (ch == "2") {
        while (1) {
            string name;
            cout << "\nName:\n";
            if(!inputEsc(name))
                return 0;
            if (!nameIsValid(name)) {
                cout << "\nSyntax Error!\n";
                continue;
            }
            if (nameExist(name)) {
                cout << "\nExistent Name!\n";
                continue;
            }
            cal->addPoly(name, cal->current);
            cout << endl << name << " = ";
            cal->printPoly(name);
            cout << " successfully saved!\n\n"
                << "Press any key to return";
            _getch();
            return -1;
        }
    }
    return 1;
}
//菜单功能 + - * == 操作
void operate(const char ch) {
    while (1) {
        system("cls");
        //打印目前功能
        if (ch == '+')
            cout << "> Polynomial Calculator > Addition\n\n";
        else if (ch == '-')
            cout << "> Polynomial Calculator > Subtraction\n\n";
        else if (ch == '*')
            cout << "> Polynomial Calculator > Multiplication\n\n";
        else if (ch == '=')
            cout << "> Polynomial Calculator > Judgement\n\n";
        //显示记录
        if (!cal->empty()) {
            cout << ">Record:\n\n";
            cal->display();
            cout << endl;
        }
        //输入左右多项式
        int flag = leftright();
        if (flag == 0)
            break;
        else if (flag == 1)
            continue;
        //对左右多项式进行相应操作
        if (ch == '+') {
            cal->current = cal->left + cal->right;
            cout << endl << "(" << cal->left << ")+(" << cal->right << ") = "
                << cal->current << endl;
        }
        else if (ch == '-') {
            cal->current = cal->left - cal->right;
            cout << endl << "(" << cal->left << ")-(" << cal->right << ") = "
                << cal->current << endl;
        }
        else if (ch == '*') {
            cal->current = cal->left * cal->right;
            cout << endl << "(" << cal->left << ")*(" << cal->right << ") = "
                << cal->current << endl;
        }
        else if (ch == '=') {
            if (cal->left == cal->right)
                cout << endl << cal->left << " = " << cal->right << endl;
            else
                cout << endl << cal->left << " != " << cal->right << endl;
        }
        //保存结果(判断相等除外)
        if (ch != '=') {
            flag = saveResult();
            if (flag == 0)
                break;
            else if (flag == -1) {
                break;
            }
        }
        //判断相等的选择返回或继续
        else{
            cout << "\nPress Esc to return, other keys to continue";
            if (_getch() == 27)
                break;
        }
        continue;
    }
}
//菜单功能
void dif() {
    while (1) {
        system("cls");
        string left;
        //打印目前功能
        cout << "> Polynomial Calculator > Differentiation\n\n";
        //显示记录
        if (!cal->empty()) {
            cout << ">Record:\n\n";
            cal->display();
            cout << endl;
        }
        //输入多项式
        cout << "Input a concrete polynominal or its name if only existed.\n\n";
        cout << "Object:\n";
        if (!inputEsc(left))
            break;
        int flag = judge(left);
        if (flag == 1 || flag == 4) {
            cout << "\nPress Esc to return, other keys to continue";
            if (_getch() == 27)
                break;
            continue;
        }
        else if (flag == 2)
            cal->left = left;
        else if (flag == 3)
            cal->left = cal->getPoly(left);
        cal->current = cal->left.differentiate();
        cout << endl << "(" << cal->left << ")' = " << cal->current << endl;
        //保存结果
        flag = saveResult();
        if (flag == 0)
            break;
        else if (flag == -1) {
            cin.ignore();
            break;
        }
        continue;
    }
}
//菜单功能
void evl() {
    while (1) {
        system("cls");
        string left, right;
        //打印目前功能
        cout << "> Polynomial Calculator > Evaluation\n\n";
        //显示记录
        if (!cal->empty()) {
            cout << ">Record:\n\n";
            cal->display();
            cout << endl;
        }
        //输入多项式
        cout << "Input a concrete polynominal or its name if only existed.\n\n";
        cout << "Object:\n";
        if (!inputEsc(left))
            break;
        int flag = judge(left);
        if (flag == 1 || flag == 4) {
            cout << "\nPress Esc to return, other keys to continue";
            if (_getch() == 27)
                break;
            continue;
        }
        else if (flag == 2)
            cal->left = left;
        else if (flag == 3)
            cal->left = cal->getPoly(left);
        //输入x的值
        float assign;
        bool tem = false;
        while (1) {
            cout << "\nx = ";
            if (!inputEsc(right)) {
                tem = true;
                break;
            }
            if (floatValid(right)) {
                const char* input = right.c_str();
                assign = (float)atof(input);
                break;
            }
            else
                cout << "\nSyntax Error!\n"; 
        }
        if (tem)
            break;
        //打印结果
        cout << endl << cal->left << " = " << cal->left.evaluate(assign) << " when x = "
            << assign << endl;
        cout << "\nPress Esc to return, other keys to continue";
        if (_getch() == 27)
            break;
        continue;
    }
}
//菜单功能
void dsp() {
    while (1) {
        system("cls");
        string left, right;
        cout << "> Polynomial Calculator > Display Record\n\n";
        if (cal->empty()) {
            cout << "Empty!\n\nPress any key to return";
            _getch();
            break;
        }
        //记录非空
        else {
            cal->display();
            //选择删除某条记录或返回
            cout << "\nPress D to delete a polynominal, Esc to return";
            char ch = _getch();
            if (ch == 'D' || ch == 'd') {
                while (1) {
                    system("cls");
                    cout << "> Polynomial Calculator > Display Record > Delete A Record\n\n";
                    cal->display();
                    string name;
                    cout << "\nName:\n";
                    if (!inputEsc(name)) {
                        ch = 27;
                        break;
                    }
                    if (!nameExist(name)) {
                        cout << "\nNon-Existent Name!\nPress Esc to return the menu, others to return\n";
                        ch = _getch();
                        break;
                    }
                    cout << "\nDelete " << name << " = ";
                    cal->printPoly(name);
                    cout << " ?\n\nPress Y to delete, Esc to return the menu, others to return.\n";
                    ch = _getch();
                    if (ch == 'y'||ch=='Y') {
                        cal->deletePoly(name);
                        cout << endl << name << " successfully deleted!";
                        cout << "\nPress Esc to return the menu, others to return";
                        ch = _getch();
                    }
                    break;
                }
            }
            if (ch == 27)
                break;
        }
    }
}
//菜单功能
void res() {
    system("cls");
    cout << "> Polynomial Calculator > Reset\n\n";
    cout << "Press Y to reset, other keys to return";
    char ch = _getch();
    if (ch == 'Y' || ch == 'y') {
        cal->clear();
        cout << "\n\nReset successfully! Press any key to return";
        _getch();
    }
}
//读文件
void read() {
    cal->read();
}
//写文件
void write() {
    cal->write();
}

Calculator.h

#pragma once
#include"Polynominal.h"
using namespace std;
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&);               \
  void operator=(const TypeName&)
class Calculator {
public:
    static Calculator* getInstance();
    static void deleteInstance();
    void addPoly(const string name, const Polynominal & poly);
    void Calculator::deletePoly(const string name);
    void printPoly(const string name);
    bool nameExist(const string name);
    void display();
    bool empty();
    Polynominal & getPoly(const string name);
    Polynominal left;
    Polynominal right;
    Polynominal current;
    void clear();
    void read();
    void write();
private:
    map<string, Polynominal> Poly;
    Calculator();
    ~Calculator();
    static Calculator* instance;
    DISALLOW_COPY_AND_ASSIGN(Calculator);
};

Calculator.cpp

#include"Calculator.h"
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip>

using namespace std;

Calculator* Calculator::instance = NULL;
Calculator* Calculator::getInstance() {
    if (instance == NULL)
        instance = new Calculator;
    return instance;
}
void Calculator::deleteInstance() {
    if (instance != NULL)
        delete instance;
    instance = NULL;
}
void Calculator::addPoly(const string name, const Polynominal & poly) {
    Poly.insert(pair<string,Polynominal>(name, poly));
}
void Calculator::deletePoly(const string name) {
    Poly.erase(name);
}
void Calculator::printPoly(const string name) {
    cout << Poly.find(name)->second;
}
bool Calculator::nameExist(const string name) {
    if (Poly.find(name) != Poly.end())
        return true;
    return false;
}
void Calculator::display() {
    for (auto & x : Poly) {
        const char* out = x.first.c_str();
        cout << "  " << setw(10) << out << " = " << x.second << endl;
    }
}
bool Calculator::empty() {
    return Poly.empty();
}
Polynominal & Calculator::getPoly(const string name) {
    return Poly.find(name)->second;
}
void Calculator::clear() {
    Poly.clear();
}
void Calculator::read() {
    ifstream in("record", ios::binary | ios::in);
    if (in.is_open()) {
        while (in.peek() != EOF) {
            string name, poly;
            getline(in, name);
            getline(in, poly);
            current = poly;
            addPoly(name, current);
        }
        in.close();
    }
}
void Calculator::write() {
    ofstream out("record", ios::binary | ios::out);
    if (out.is_open()) {
        for (auto x : Poly) {
            const char* name = x.first.c_str();
            out << name << endl;
            for (auto y : x.second.Term)
                out << "(" << y.second << "," << y.first << ")";
            out << endl;
        }
        out.close();
    }
    else {
        cerr << "Unknown Error!";
        system("pause");
    }
}
Calculator::~Calculator() {
    Poly.clear();
}
Calculator::Calculator() {}

Polynominal.h

#pragma once
#include<map>
//#include"Term.h"
using namespace std;
class Polynominal {
public:
    Polynominal();
    Polynominal(const Polynominal & source);
    Polynominal(const string input);
    ~Polynominal();
    Polynominal operator+(const Polynominal & right);
    Polynominal operator-(const Polynominal & right);
    Polynominal operator*(const Polynominal & right);
    Polynominal & operator=(const Polynominal & source);
    Polynominal & operator=(const string Input);
    Polynominal differentiate();
    float evaluate(float num);
    bool operator==(const Polynominal & other);
    bool invalid_0();
    bool empty();
    friend ostream & operator<<(ostream & out, const Polynominal & Poly);

    map<int, float> Term;
    void addTerm(int exp, float coef);
};

Polynominal.cpp

#include"Polynominal.h"
#include<string>
#include<cmath>
#include<sstream>
using namespace std;
Polynominal::Polynominal(){}
Polynominal::Polynominal(const Polynominal & source) {
    for (auto & x : source.Term)
        Term.insert(pair<int, float>(x.first, x.second));
}
Polynominal::Polynominal(const string input) {
    int count = 0;
    for (size_t i = 0; i < input.length(); i++)
        if (input[i] == '(')
            count++;
    stringstream in(input);
    for (int i = 0; i < count; i++) {
        int exp;
        float coef;
        char ch;
        in >> ch >> coef >> ch >> exp >> ch;
        addTerm(exp, coef);
    }
}
Polynominal::~Polynominal() {
    Term.clear();
}
Polynominal Polynominal::operator+(const Polynominal & right) {
    Polynominal des(*this);
    for (auto & x : right.Term)
        des.addTerm(x.first, x.second);
    return des;
}
Polynominal Polynominal::operator-(const Polynominal & right) {
    Polynominal des(*this);
    for (auto & x : right.Term)
        des.addTerm(x.first, x.second*(-1));
    return des;
}
Polynominal Polynominal::operator*(const Polynominal & right) {
    Polynominal result;
    for (auto & i : Term)
        for (auto & j : right.Term)
            result.addTerm(i.first + j.first, i.second*j.second);
    return result;
}
Polynominal & Polynominal::operator=(const Polynominal & source) {
    Term.clear();
    for (auto & x : source.Term)
        Term.insert(pair<int, float>(x.first, x.second));
    return *this;
}
Polynominal & Polynominal::operator=(const string Input) {
    Term.clear();
    string input = Input;
    while (1) {
        stringstream in(input);
        int exp;
        float coef;
        char ch;
        in >> ch >> coef >> ch >> exp >> ch;
        addTerm(exp, coef);
        size_t pos = input.find(')') + 1;
        if (pos >= input.length())
            break;
        input = input.substr(pos);
    }
    return *this;
}
float Polynominal::evaluate(float num) {
    float value = 0;
    for (auto & x : Term)
        value += x.second*pow(num, x.first);
    return value;
}
Polynominal Polynominal::differentiate() {
    Polynominal result;
    for (auto & x : Term)
        if (x.first != 0)
            result.addTerm(x.first - 1, x.second*x.first);
    return result;
}
bool Polynominal::operator==(const Polynominal & other) {
    auto iter = other.Term.begin();
    for (auto & x : Term) {
        if (iter == other.Term.end())
            return false;
        if (x.first != iter->first || fabs(x.second - iter->second) >= 1e-6)
            return false;
        iter++;
    }
    return true;
}
bool Polynominal::invalid_0() {
    auto iter = Term.begin();
    if (iter->first < 0)
        return true;
    return false;
}
bool Polynominal::empty() {
    return Term.empty();
}
ostream & operator<<(ostream & out, const Polynominal & Poly) {
    if (Poly.Term.empty())
        out << "0";
    else {
        for (auto iter = Poly.Term.rbegin(); iter != Poly.Term.rend(); iter++) {
            if (iter->first == 0)
                out << iter->second;
            else {
                if (fabs(iter->second + 1) < 1e-6)
                    out << "-";
                else if (fabs(iter->second - 1) >= 1e-6)
                    out << iter->second;
                out << "x";
                if (iter->first != 1) {
                    if (iter->first > 0)
                        out << "^" << iter->first;
                    else
                        out << "^" << "(" << iter->first << ")";
                }
            }
            auto itor = iter;
            if (++itor != Poly.Term.rend() && itor->second > 0)
                out << "+";
        }
    }
    return out;
}
void Polynominal::addTerm(int exp, float coef) {
    if (fabs(coef) < 1e-6)
        return;
    auto iter = Term.find(exp);
    if (iter == Term.end())
        Term.insert(pair<int, float>(exp, coef));
    else {
        iter->second += coef;
        if (fabs(iter->second) < 1e-6)
            Term.erase(iter);
    }
}
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值