思路:
首先要考虑存储多项式,只需存它每一项的系数和指数,用队列来存储比较方便,所以需要调用之前的链表队
列,将每一项的指数和系数当做一个数据存入队列。然后简单的加减乘除运算可以套用计算器(栈的应用),
只需将Stack_entry类型换为多项式即可。
**要求:**运算的多项式必须按未知数指数从大到小排列。
**多项式加法:**对比两个多项式的指数,指数相同的系数相加。
**多项式减法:**对比两个多项式的指数,指数相同的系数相减。
**多项式乘法:**将一个多项式拆开,让其每一项都与另一个多项式相乘,最后所有结果相加。
多项式除法:
需要递归,将被除数首项和除数首项取出相除,结果记为一部分商,余数继续取出首 项和除数首项相除,将结果与前面求出的部分商相加,以此循环,直到余数小于除数。
说明:
chainqueue.cpp可参考之前的博客:用链表存储队列。
stack.cpp可参考之前的博客:用c++程序实现栈。
代码:
term.h
struct Term { //定义结构体存储多项式的一项
int degree; //指数
double coefficient; //系数
Term (int exponent = 0, double scalar = 0); //构造函数
};
Term::Term(int exponent, double scalar) //构造函数
{
degree = exponent;
coefficient = scalar;
}
polynomial.cpp
#include "term.h"
typedef Term Nodequeue_entry;
typedef Nodequeue_entry Queue_entry;
#include "chainqueue.cpp"
class Polynomial: private Extended_queue { //调用扩展队列
public:
void read(); //读取
void print() const; //打印
void equals_sum(Polynomial p, Polynomial q); //加法
void equals_difference(Polynomial p, Polynomial q); //减法
void equals_product(Polynomial p, Polynomial q); //乘法
Error_code equals_quotient(Polynomial p, Polynomial q); //除法
int degree() const; //读取首项的指数
private:
void mult_term(Polynomial p, Term t); //求多项式与一项的乘积
};
void Polynomial::mult_term(Polynomial p, Term t) //求多项式与一项的乘积
{
clear(); //清空链表
while(!p.empty()) //遍历p
{
Term pterm;
p.serve_and_retrieve(pterm); //读出首项元素并删除
Term answer_term(pterm.degree + t.degree,t.coefficient * pterm.coefficient); //计算,指数相加,系数相乘
append(answer_term); //将每一项的结果存起来
}
}
void Polynomial::print() const //打印
{
Nodequeue *print_node = front;
bool first_term = true;
while (print_node != NULL) { //检测是否有数据
Term &print_term = print_node->entry; //定义一项并将头节点的数据赋给它
if (first_term) {
first_term = false;
if (print_term.coefficient < 0) cout << "- ";
}
else if (print_term.coefficient < 0) cout << " - ";
else cout << " + "; //打印各项之间的符号
double r = (print_term.coefficient >= 0)
? print_term.coefficient : -(print_term.coefficient);
if (r != 1) cout << r; //打印系数
if (print_term.degree > 1) cout << " X^" << print_term.degree;
if (print_term.degree == 1) cout << " X";//打印指数部分
if (r == 1 && print_term.degree == 0) cout << " 1";
print_node = print_node->next; //遍历
}
if (first_term)
cout << "0";
cout << endl;
}
void Polynomial::read() //读取
{
clear(); //清空链表
double coefficient; //系数
int last_exponent, exponent;
bool first_term = true;
cout << "Enter the coefficients and exponents for the polynomial, "
<< "one pair per line. Exponents must be in descending order." << endl
<< "Enter a coefficient of 0 or an exponent of 0 to terminate." << endl; //提示输入规则
do {
cout << "coefficient? " << flush;
cin >> coefficient; //获取系数
if (coefficient != 0.0)
{
cout << "exponent? " << flush;
cin >> exponent; //获取指数
if ((!first_term && exponent >= last_exponent) || exponent < 0) {
exponent = 0;
cout << "Bad exponent: Polynomial terminates without its last term."
<< endl; //如果输入指数比上次的指数大,则提示错误
}
else {
Term new_term(exponent, coefficient);
append(new_term); //存入链表
first_term = false;
}
last_exponent = exponent;
}
} while (coefficient != 0.0 && exponent != 0);
}
void Polynomial::equals_sum(Polynomial p, Polynomial q) //加法
{
clear(); //清空链表
while (!p.empty() || !q.empty())
{ //若两个链表同时为空则不用执行操作
Term p_term, q_term; //定义两项分别用来存储两个多项式的和
if (p.degree() > q.degree())
{
p.serve_and_retrieve(p_term);
append(p_term);
} //如果p的首项指数大于q的首项指数则读出并删除p的首项,将结果存入p_term中
else if (q.degree() > p.degree())
{
q.serve_and_retrieve(q_term);
append(q_term);
} //如果q的首项指数大于p的首项指数则读出并删除q的首项,将结果存入q_term中
else { //如果两个多项式首项指数相等,则执行下面操作
p.serve_and_retrieve(p_term); //读取并删除p的首项
q.serve_and_retrieve(q_term); //读取并删除q的首项
if (p_term.coefficient + q_term.coefficient != 0)
{ //判断两个多项式首项是否可抵消
Term answer_term(p_term.degree,p_term.coefficient + q_term.coefficient); //将两个首项系数相加,指数不变
append(answer_term); //将结果存入链表中
}
}
}
}
void Polynomial::equals_difference(Polynomial p, Polynomial q) //减法
{
clear(); //清空链表
Term p_term, q_term; //定义两项分别用来存储两个多项式运算的值
while (!p.empty() || !q.empty())
{ //若两个链表同时为空则不用执行操作
if (p.degree() > q.degree())
{
p.serve_and_retrieve(p_term);
append(p_term);
} //如果p的首项指数大于q的首项指数则读出并删除p的首项,将结果存入p_term中
else if (q.degree() > p.degree())
{
q.serve_and_retrieve(q_term);
q_term.coefficient = -q_term.coefficient;
append(q_term);
} //如果q的首项指数大于p的首项指数则读出并删除q的首项,将q指数的相反数存入q_term中
else { //如果两个多项式首项指数相等,则执行下面操作
p.serve_and_retrieve(p_term); //读取并删除p的首项
q.serve_and_retrieve(q_term); //读取并删除q的首项
if (p_term.coefficient - q_term.coefficient != 0)
{ //判断两个多项式首项是否可抵消
Term answer_term(p_term.degree,p_term.coefficient - q_term.coefficient); //将两个首项系数相减,指数不变
append(answer_term); //将结果存入链表中
}
}
}
}
void Polynomial::equals_product(Polynomial p, Polynomial q) //乘法
{
clear(); //清空链表
Term p_term, term; //p_term用来存储p的每一项,term用来存最终的结果
Polynomial partial_prod,old_sum,new_sum; //partial_prod用来存当前项与q的乘积
while(p.serve_and_retrieve(p_term) == success) //遍历p
{
partial_prod.mult_term(q,p_term); //将p的当前项与q相乘
new_sum.equals_sum(old_sum,partial_prod); //新的和等于上次的多项式加这次的多项式
old_sum = new_sum; //将新的和赋给上次多项式
}
while(new_sum.serve_and_retrieve(term) == success) append(term); //遍历完后,将结果存入链表
}
Error_code Polynomial::equals_quotient(Polynomial p, Polynomial q) //除法
{
clear(); //清空链表
if(q.empty()) return fail; //若除数为0则算式不成立
if(p.degree() < q.degree()) return success; //如果被除数的首项次幂大于除数的首项次幂则不用计算
Term p_term,q_term,term; //p_term表示p的当前项,q_term表示q的当前项
Polynomial partial_prod,remainder,tail; //partial_prod表示当前结果,remainder
p.serve_and_retrieve(p_term); //读取p首项并删除
q.retrieve(q_term); //读取q的首项
Term lead_term(p_term.degree - q_term.degree,p_term.coefficient / q_term.coefficient); //首项相除
append(lead_term); //首项相除结果保存
partial_prod.mult_term(q,lead_term); //将上次得到的商与除数相乘
partial_prod.serve_and_retrieve(term); //取出首项
remainder.equals_difference(p,partial_prod); //相减得余数
tail.equals_quotient(remainder,q); //递归
while(tail.serve_and_retrieve(term) == success) append(term); //将最终结果存入链表
return success;
}
int Polynomial::degree() const //读取首项的指数
{
if (empty()) return -1; //如果是空表则返回-1
Term lead;
retrieve(lead); //读取首项数据
return lead.degree; //返回首项的指数
}
main.cpp
#include "polynomial.cpp"
typedef Polynomial Stack_entry;
#include "stack.cpp"
void introduction() //说明程序作用
{
cout << "Reverse Polish Calculator Program." << "\n----------------------------------" << endl << endl;
}
void instructions() //说明输入规则
{
cout << "User commands are entered to read in and operate on integers." << endl;
cout << "The valid commands are as follows:" << endl << "[Q]uit." << endl;
cout << "[?] to enter an integer onto a stack." << endl << "[=] to print the top integer in the stack." << endl;
cout << "[+] [-] [*] [/] are arithmetic operations." << endl << "These operations apply to the top pair of stacked integers." << endl;
}
char get_command() //检测输入的字符是否有效
{
char command;
bool waiting = true;
cout << "Select command and press :" ;
while (waiting) {
cin >> command;
command = tolower(command);
if (command == '?' || command == '=' || command == '+' ||
command == '-' || command == '*' || command == '/' ||
command == 'q' ) waiting = false; //当输入合法时给waiting赋false,跳出循环,执行操作
else {
cout << "Please enter a valid command:" << endl
<< "[?]push to stack [=]print top" << endl
<< "[+] [-] [*] [/] are arithmetic operations" << endl
<< "[Q]uit." << endl; //当输入不合法时,提示重新输入
}
}
return command;
}
bool do_command(char command, Stack &stored_polynomials)
{
Polynomial p, q, r;
switch (command) {
case '?':
p.read();
if (stored_polynomials.push(p) == overflow)
cout << "Warning: Stack full, lost polynomial" << endl;
break;
case '=':
if (stored_polynomials.empty())
cout << "Stack empty" << endl;
else {
stored_polynomials.top(p);
p.print();
}
break;
case '+':
if (stored_polynomials.empty())
cout << "Stack empty" << endl;
else {
stored_polynomials.top(p);
stored_polynomials.pop();
if (stored_polynomials.empty()) {
cout << "Stack has just one polynomial" << endl;
stored_polynomials.push(p);
}
else {
stored_polynomials.top(q);
stored_polynomials.pop();
r.equals_sum(q, p);
if (stored_polynomials.push(r) == overflow)
cout << "Warning: Stack full, lost polynomial" << endl;
}
}
break;
case 'q':
cout << "Calculation finished." << endl;
return false;
}
return true;
}
int main()
{
Stack stored_polynomials;
void introduction();
void instructions();
while (do_command(get_command(), stored_polynomials));
}