多项式的简单运算(栈和队列的应用)

思路:

   首先要考虑存储多项式,只需存它每一项的系数和指数,用队列来存储比较方便,所以需要调用之前的链表队
   列,将每一项的指数和系数当做一个数据存入队列。然后简单的加减乘除运算可以套用计算器(栈的应用),
   只需将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 <Enter>:";

   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));
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

格格不入ち

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值