C++求解形如“a/b x + d/c = f/e”的一元一次分式方程

思路比较清晰

1.从命令行读入方程

2.解析字符串,解析出几个参数a/b,d/c,f/e

3.Rational类定义了分数的运算,代入运算即可

这个小程序的结构

\---main.cpp       程序的入口

|---rational.h      分数类的声明

|---Rational.cpp分数类的实现

|---myException.h定义几个异常类

|---test.cpp单独使用,测试Rational类

代码如下

main.cpp

#include "rational.h"
#include "Rational.cpp"

using namespace std;

int main(){
while(1){
    cout << "输入方程:形如a/b x + d/c = f/e"<<endl;
    char Arr[50];
    cin.getline(Arr, 50);
    string equation(Arr);
   // cout << equation <<endl;
//   a/b x + d/c = f/e
    int pos_x = equation.find('x',0);
    int pos_p = equation.find('+',0);
    int pos_e = equation.find('=',0);

    Rational coe( equation.substr(0,pos_x) );// a/b
    Rational b( equation.substr(pos_p+1,pos_e - pos_p) );// d/c
    Rational c( equation.substr(pos_e+1,equation.length()-pos_e) );// f/e

 //   cout<<"coe = "<<coe<<endl;
 //   cout<<"b = "<<b<<endl;
 //   cout<<"c = "<<c<<endl;
    if(coe.getNumer() == 0 && b.isEqual(c)) cout<<"x ∈ Q"<<endl;
    else if(coe.getNumer() == 0 && !b.isEqual(c)) cout<<"无解"<<endl;
    else  cout<<"解得 x = "<<(c-b)/coe<<endl<<endl;

    system("pause");
    system("cls");
}
}

rational.h

#ifndef Rational_
#define Rational_
#include "myException.h"
#include<iostream>
using namespace std;

class Rational{
public:
    Rational(int x, int y);//传入分子分母构造分数
    Rational(string s);//从字符串构造分数
    Rational nega();//相反数
    Rational reci();//倒数
    bool isEqual(Rational that);
    Rational add(Rational that);//加法
    Rational sub(Rational that);//减法
    Rational mul(Rational that);//乘法
    Rational div(Rational that);//除法
    void Output(ostream &out)const;//输出方法
    int getNumer(){return numer;}
    int getDenom(){return denom;}
private:
    int numer;//分子
    int denom;//分母
    int gcd(int a, int b) const { return (b==0) ? a : gcd(b, a % b); }//最大公约数
};
#endif // Rational_define

Rational.cpp

#include "rational.h"
#include "myException.h"
#include<cstdlib>

using namespace std;

Rational::Rational(int x, int y){//传入分子分母构造分数
    if(y==0) throw new illegalDenominatorValue();
    numer = x;
    denom = y;
}
//从字符串构造分数
Rational::Rational(string s){
    int pos = s.find('/',0);
    if(pos <= 0 || pos >= s.length()-1) throw new illegalInputExpression();
    numer = atoi( s.substr(0,pos).c_str() );
    denom = atoi( s.substr(pos+1,s.length()-pos-1).c_str() );
    if(denom == 0 ) throw new illegalDenominatorValue();
}
//相反数
Rational Rational::nega(){
    return Rational(-numer, denom);
}
//倒数
Rational Rational::reci(){
    if(numer == 0) throw new NoReciprocal();
    return Rational(denom,numer);
}
//相等
 bool Rational::isEqual(Rational that){
    return numer * that.denom == denom * that.numer;
 }
//加法
Rational Rational::add(Rational that){
    return Rational(numer * that.denom + denom * that.numer,denom * that.denom);
}
//减法
Rational Rational::sub(Rational that){
    return add(that.nega());
}
//乘法
Rational Rational::mul(Rational that){
    return Rational(numer  *  that.numer, denom * that.denom);
}
//除法
Rational Rational::div(Rational that){
    return mul(that.reci());
}
//输出
 void Rational::Output(ostream &out)const{
        int c = gcd(numer,denom);
       // int c = 1;
        out<<numer/c<<"/"<<denom/c;
 }
 //输出操作符重载
ostream& operator<<(ostream& out, const Rational& r){
    r.Output(out);
    return out;
}
//操作符重载
Rational operator +(Rational a, Rational b){
    return a.add(b);
}
Rational operator -(Rational a, Rational b){
    return a.sub(b);
}
Rational operator *(Rational a, Rational b){
    return a.mul(b);
}
Rational operator /(Rational a, Rational b){
    return a.div(b);
}

myException.h

// exception classes for various error types

#ifndef myExceptions_
#define myExceptions_
#include <string>
#include<iostream>
using namespace std;

// illegal Denominator value
class illegalDenominatorValue
{
   public:
      illegalDenominatorValue(string theMessage = "Denominator must be nonezero!"){
          message = theMessage;
      }
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// illegal input Expression
class illegalInputExpression
{
   public:
      illegalInputExpression(string theMessage = "Illegal  input Expression"){
          message = theMessage;
      }
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};
//倒数
class NoReciprocal
{
   public:
      NoReciprocal(string theMessage = "No Reciprocal with numerator=0"){
          message = theMessage;
      }
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};
#endif

test.cpp

#include "rational.h"
#include "Rational.cpp"
using namespace std;
int main(){
    Rational a(1,2);
    Rational b("1/4");
    //Rational c("1/0");
    //Rational c("1/");
    cout<<"a =  \t"<<   a       <<endl;
    cout<<"b =  \t"<<   b       <<endl;
    cout<<"-a = \t"<<   a.nega()<<endl;
    cout<<"1/b =\t"<<   b.reci()<<endl;

    cout<<"a.add(b) =\t"<<   a.add(b)<<endl;
    cout<<"a.sub(b) =\t"<<   a.sub(b)<<endl;
    cout<<"a.mul(b) =\t"<<   a.mul(b)<<endl;
    cout<<"a.div(b) =\t"<<   a.div(b)<<endl;

    cout<<"a+b =\t"<<   a+b<<endl;
    cout<<"a-b =\t"<<   a-b<<endl;
    cout<<"a*b =\t"<<   a*b<<endl;
    cout<<"a/c =\t"<<   a/b<<endl;

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-25 12:26:37

C++求解形如“a/b x + d/c = f/e”的一元一次分式方程的相关文章

如何优雅的实现一个C++分数类(Rational) ?

什么样的Rational类实现算是优雅? 在我看来它应该符合以下几个特点 1.符合面向对象的封装特性,数据隐藏(因为只有一个类,没有考虑封装和多态). 2.声明与实现相分离,接口清晰,自然,既有足够的基本功能又不冗余. 3.代码简洁清晰 4.最好不加注释就能看懂,变量名,方法名能够见名知义 5.do not repeat yourself,不要做重复的工作 6.出错时抛出异常,中止程序,而不是将错误掩盖在内部实现之中,埋下隐患. 下面的这个Rational实现我认为是比较优雅的,它符合上面的5个

分治策略(求解递归式的方法)

分解:将原问题划分成形式相同的子问题,规模可以不等,对半或2/3对1/3的划分. 解决:对于子问题的解决,很明显,采用的是递归求解的方式,如果子问题足够小了,就停止递归,直接求解. 合并:将子问题的解合并成原问题的解. 这里引出了一个如何求解子问题的问题,显然是采用递归调用栈的方式.因此,递归式与分治法是紧密相连的,使用递归式可以很自然地刻画分治法的运行时间.所以,如果你要问我分治与递归的关系,我会这样回答:分治依托于递归,分治是一种思想,而递归是一种手段,递归式可以刻画分治算法的时间复杂度.

[Matlab]求解线性方程组

转自:http://silencethinking.blog.163.com/blog/static/911490562008928105813169/ AX=B或XA=B在MATLAB中,求解线性方程组时,主要采用前面章节介绍的除法运算符“/”和“\”.如: X=A\B表示求矩阵方程AX=B的解: X=B/A表示矩阵方程XA=B的解. 对方程组X=A\B,要求A和B用相同的行数,X和B有相同的列数,它的行数等于矩阵A的列数,方程X=B/A同理. 如果矩阵A不是方阵,其维数是m×n,则有: m=

[NOIP提高&amp;洛谷P1024]一元三次方程求解 题解(二分答案)

[NOIP提高&洛谷P1024]一元三次方程求解 Description 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1.要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位. 提示:记方程f(x)=0,若存在2个数x1和x2,且x1<x2,f(x1)*f(x2)<0,则在(x1,x2)之间一定

一个求解平方根的算法题

1. 问题描述 问题是这样子的,给定一个数a,求解这个数的平方根,要求精度f<0.0001. 好久没有操刀实现算法代码了,今天就来写一个小的,后续算法依旧是研究的重点.比较软件中,算法是核心是灵魂啊! 2. 算法分析 说起来,这个算法题其实不是太麻烦,主要采取的就是不断试探,逼近真是目标值的思路,最容易想到的就是,不断的折半逼近,有点类似二分的思想.同时,一个重要的思想: 1. 设目标值平方根为Se 2. 待求解的输入数据为St 3. |Se*Se - St| < f*f 4. 求出一个Se*

【算法整理】听说你写的算法很牛?-优质算法衡量标准探讨

引文 我有个朋友有算法强迫症,每次一看到别人写的算法,就有上去改的冲动,不然就会偏头疼,主要症结在于他认为别人写的算法不好,但是什么的算法可以评判为好,什么样的算法可以评判为不好?最近为了治愈他,我特地写了这篇文章. 算法的衡量从两个方向出发:时间复杂度和空间复杂度.本文主要是不讲具体算法,只将算法的衡量,重点讲解如何衡量算法的复杂度,解决平时见到的XX算法时间复杂是O(logn)O(logn),其中这个结果是怎么推导出来的?lognlogn是个什么玩意儿?,大写的OO是什么意思?为什么用这个符

[施工中]良心数论.

/* Copyright: xjjppm Author: xjjppm Date: 08-08-17 11:36 Description: Number Theory */ #include <map> #include <cmath> #include <cstdio> #include <cstring> #include <algorithm> inline int input() { char c=getchar();int x=0,a=

扩展欧几里德算法

文章来源:http://blog.csdn.net/zhjchengfeng5/article/details/7786595 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了

分治策略 &nbsp; 最大子数组问题

递归式 递归式与分治方法是紧密相关的,因为使用递归式可以很自然地刻画分治算法的运行时间.一个递归式就是一个等式或不等式,它通过更小的输入上的函数值来描述一个函数.例如,在2.3.2节,我们用递归式描述了MERGE-SORT过程的最坏情况运行时间T(n): Θ(1)        若n=1 T(n) =                         (4.1) 2T(n/2)+Θ(n)    若n>1 求解可得T(n)=Θ(nlgn) 递归式可以有很多形式.例如,一个递归算法可能将问题划分为规模