题目描述
一元二次方程可以分成三类:有两个不相等的实根、有两个相等的实根、有两个共轭复根。可以从中抽象出一个基类,在基类中声明一个虚函数,用来显示它们的根。编写主程序,要求通过调用虚函数分别输出三种情况下二次方程的根。
解析
题意理解
题意十分简单,给定一个一元二次方程,判定根的情况并输出对应的根即可。
题目分析
如果不考虑面向对象的写法,直接在main函数中写的话,这道题没有任何难度,直接判断三种情况然后输出对应的根,但由于题目说明要在基类中声明虚函数,这就加大了本题的门槛了,要写本题得先明白啥是虚函数
代码实现思路
step1
首先我们要想办法读入一个形如 Ax^2 Bx C = 0 的形式,我们会发现只要读入A, B, C就可以了,接着是判断这个方程的根属于哪一种类型。
代码语言:javascript复制void solve(){
cout << "请输入形如:'Ax ^ 2 Bx C = 0' 对应的系数 A, B, C" << endl;
double a, b, c;
cin >> a >> b >> c;
int flg = check(a, b, c); // check函数自己实现
// 根据flg的值分三种情况讨论
if()
else if()
else
}
tips
这步实现完成之后记得输出一下看下自己判断的是否正确再开始下一步
step2
接着考虑一下用class的实现, 首先我们应该定义一个class Base(基类), 在这里面我们要声明虚函数
以及设置public
或protected
类的成员a, b, c。不能设置成private
是因为该基类的派生类(子类)是访问不了基类的private
成员的。
class Base{
public:
Base(double a, double b, double c){
this->a = a, this->b = b, this->c = c;
}
virtual void print_root() = 0; // 设置成纯虚函数
public:
double a, b, c;
};
step3
求方程的根也就没什么好说的了
但这边提醒一个点:因为是用double
型存数据,会有精度问题,所以要判断根 ==
0的时候最好特殊用一个eps
处理一下。
我们首先考虑第一种两种实根相等的情况即:B^2 - 4AC == 0 这种情况
代码语言:javascript复制class State1:public Base{
public:
State1(double a, double b, double c):Base(a, b, c){ // 调用基类构造函数
}
void save(){ // 计算x1, x2 并将结果存到root1和root2中
double a = this->a, b = this->b, c = this->c;
this->root1 = this->root2 = (-1 * b) / (1.0 * 2 * a);
}
void print_root(){ // 重写父类的print_root()函数
printf("x1 = %.2lfnx2 = %.2lfn", this->root1, this->root2);
}
private:
double root1, root2; // 两个根
};
接着是 B^2 - 4AC > 0
代码语言:javascript复制class State2:public Base{
public:
State2(double a, double b, double c):Base(a, b, c){
}
void save(){
double a = this->a, b = this->b, c = this->c;
double delta = sqrt(b * b - 4 * a * c);
this->root1 = (-1 * b delta) / (1.0 * 2 * a);
this->root2 = (-1 * b - delta) / (1.0 * 2 * a);
}
void print_root(){
printf("x1 = %.2lfnx2 = %.2lfn", this->root1, this->root2);
}
private:
double root1, root2;
};
最后是 B^2 - 4AC < 0
代码语言:javascript复制class State3:public Base{
public:
State3(double a, double b, double c):Base(a, b, c){
}
void save(){
double a = this->a, b = this->b, c = this->c;
double delta = sqrt(4 * a * c - b * b);
this->real = (-1 * b) / (1.0 * 2 * a);
this->img = delta / (1.0 * 2 * a);
}
void print_root(){
printf("x1 = %.2lf %.2lfinx1 = %.2lf-%.2lfin", this->real, this->img, this->real, this->img);
}
private:
double real, img; // 实部和虚部
};
最终代码实现
代码语言:javascript复制#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iomanip>
#include <cstdio>
using namespace std;
const double eps = 1e-6;
class Base{
public:
Base(double a, double b, double c){
this->a = a, this->b = b, this->c = c;
}
virtual void print_root() = 0;
public:
double a, b, c;
};
class State1:public Base{
public:
State1(double a, double b, double c):Base(a, b, c){
}
void save(){
double a = this->a, b = this->b, c = this->c;
this->root1 = this->root2 = (-1 * b) / (1.0 * 2 * a);
}
void print_root(){
printf("x1 = %.2lfnx2 = %.2lfn", this->root1, this->root2);
}
private:
double root1, root2;
};
class State2:public Base{
public:
State2(double a, double b, double c):Base(a, b, c){
}
void save(){
double a = this->a, b = this->b, c = this->c;
double delta = sqrt(b * b - 4 * a * c);
this->root1 = (-1 * b delta) / (1.0 * 2 * a);
this->root2 = (-1 * b - delta) / (1.0 * 2 * a);
}
void print_root(){
printf("x1 = %.2lfnx2 = %.2lfn", this->root1, this->root2);
}
private:
double root1, root2;
};
class State3:public Base{
public:
State3(double a, double b, double c):Base(a, b, c){
}
void save(){
double a = this->a, b = this->b, c = this->c;
double delta = sqrt(4 * a * c - b * b);
this->real = (-1 * b) / (1.0 * 2 * a);
this->img = delta / (1.0 * 2 * a);
}
void print_root(){
printf("x1 = %.2lf %.2lfinx1 = %.2lf-%.2lfin", this->real, this->img, this->real, this->img);
}
private:
double real, img;
};
int check(double a, double b, double c){
double delta = b * b - 4 * a * c;
if(delta >= 0 && delta < eps)
return 0;
if(delta > eps)
return -1;
return 1;
}
void solve(){
cout << "请输入形如:'Ax ^ 2 Bx C = 0' 对应的系数 A, B, C" << endl;
double a, b, c;
cin >> a >> b >> c;
int flg = check(a, b, c);
if(!flg) // 等价于 if(flg == 0)
{
State1 s(a, b, c);
s.save();
s.print_root();
}
else if(!~flg) 等价于 if(flg == -1)
{
State2 s(a, b, c);
s.save();
s.print_root();
}
else
{
State3 s(a, b, c);
s.save();
s.print_root();
}
}
int main(){
cout.setf(ios::fixed);
cout << fixed << setprecision(2);
solve();
return 0;
}