您的位置:首页 > 编程语言 > C语言/C++

C++解一元二次方程。以字符串ax^2+bx+c=d(d>=0)的形式输入

2013-02-27 15:18 134 查看
显然在这个题目中,如何解析输入的字符创是主要问题,我的思路是用'+',‘-’,‘=’分段这个字符串,并将每段的开头用一个vector变量记录下来(第一段开始点为0,要手动加入),如分成ax^2    bx     c    d 这样几段

然后以每段的开始为起点,每段的结束为终点,历遍字符串的特定部分。用变量int fengjie 记录下每段的系数的结尾位置 ,若循环时该字符为数字,则fengjie ++,否则记录数字,并判断数字后的项是二次项还是一次项还是常数。然后将数字输入到对应变量。

运行结果图



第一次发文,代码中的不足之处,请各位牛人们不要吝惜您的板砖,感谢您指出我的不足

下面上代码

//fangcheng.h
#pragma once
#include <string>
class fangcheng
{
public:
fangcheng(void);
~fangcheng(void);
// 执行解方程
bool jie(void);
// 打印解的结果
void print(void);
void input(void);
// 解析字符串
void jiexiStr(std::string);
private:
double m_vA;// 一元二次方程的a
double m_vB;// 一元二次方程的b
double m_vC;// 一元二次方程的c
double x1;
double x2;
bool isOK;
std::string strFangcheng;
};

//fangcheng.cpp
#include "StdAfx.h"
#include "fangcheng.h"
#include <iostream>
#include <cmath>
#include <sstream>
#include <vector>
fangcheng::fangcheng(void)	: x1(0), x2(0), isOK(false),m_vA(0),m_vB(0),m_vC(0)
{
std::cout<<"方程对象已建立,请以ax^2+bx+c=d(d>=0)的形式输入一元二次方程,其中系数为0的项目可以省略"<<std::endl;
input();
}

fangcheng::~fangcheng(void)
{
}

// 执行解方程
bool fangcheng::jie(void)
{
if(pow(m_vB,2)-4*m_vA*m_vC>=0)
{
x1=(-m_vB+sqrt(pow(m_vB,2)-4*m_vA*m_vC))/(2*m_vA);
x2=(-m_vB-sqrt(pow(m_vB,2)-4*m_vA*m_vC))/(2*m_vA);
isOK=true;
return true;
}else
{
std::cout<<"您输入的方程无实数根"<<std::endl;
return false;
}
}

// 打印解的结果
void fangcheng::print(void)
{
if(!isOK)
return;
if(x1==x2)
{
std::cout<<"您输入的方程有两个相同的实数根:x="<<x1<<std::endl;
}
else
{
std::cout<<"您输入的方程有两个个根:x1="<<x1<<"    "<<"x2="<<x2<<std::endl;
}
}

void fangcheng::input(void)
{
std::cin>>strFangcheng;
jiexiStr(strFangcheng);
}

// 解析字符串
void fangcheng::jiexiStr(std::string)
{
//以ax^2+bx+c=d(d>=0)的形式输入一元二次方程,其中系数为0的项可以省略
if(strFangcheng.empty())
{
std::cout<<"方程未输入"<<std::endl;
return;
}
//以+,-,=为关键字符,记录下其位置以供下一步分段讨论
std::vector<int> mainPoint;mainPoint.push_back(0);//以每个元素为一段的开头,故除了关键点外需要手动添加0
int countLoop=0;//用来记录当前循环的次数,也就是当前字符的位置
for(std::string::iterator index=strFangcheng.begin();index!=strFangcheng.end();index++,countLoop++)
{
if(*index=='+'||*index=='-'||*index=='=')
mainPoint.push_back(countLoop+1);//+1是为了让每段的起始字符不是运算符号,而是数字,简化之后的分析
}
//开始分段讨论
for(std::vector<int>::iterator index=mainPoint.begin();index!=mainPoint.end();index++)
{
//计算该段的结束点
int theEnd;
if(index+1==mainPoint.end())
theEnd=strFangcheng.size();
else
theEnd=*(index+1)-1;

std::string::iterator strIndex=strFangcheng.begin()+*index;//准备开始历遍当前段字符串
int fengjie=*index;//fengjie用于区分每一段中前面的数字和后面的变量
for(;strIndex!=strFangcheng.begin()+theEnd;strIndex++)
{
if(!(((*strIndex)>='0'&&(*strIndex)<='9')||(*strIndex)=='x'||(*strIndex)=='^'))
{
std::cout<<"解析失败,含有未知符号:"<<*strIndex<<std::endl;
break;
}
if((*strIndex)>='0'&&(*strIndex)<='9')
{
fengjie++;//当前为数字,某些项全为数字,如c,d,需要放在这里面讨论
if((strIndex+1)<strFangcheng.end()&&*(strIndex+1)=='='&&*(strIndex)!='x')
{
std::stringstream ss( std::string(strFangcheng,*index,fengjie) );
ss>>m_vC;
if(*index>0&&*(strFangcheng.begin()+(*index-1))=='-')
m_vC=-m_vC;
}
if(strIndex+1==strFangcheng.end()&&*(strFangcheng.begin()+(*index-1))=='=')//等号右边的值
{
std::stringstream ss( std::string(strFangcheng,*index,fengjie) );
double temp;ss>>temp;
m_vC-=temp;
}
}else{
std::stringstream ss( std::string(strFangcheng,*index,fengjie) );//不是数字了,将前面的数字写入
if(*strIndex=='x'&&*(strIndex+1)=='^')//判断该项为一次项还是二次项,将数字写入相应变量,并检查改项的符号
{
if(*index!=fengjie)
{
ss>>m_vA;
if(*index>0&&*(strFangcheng.begin()+(*index-1))=='-')
m_vA=-m_vA;
}else m_vA=1;
}
if(*strIndex=='x'&&*(strIndex+1)!='^')
{
if(*index!=fengjie)
{
ss>>m_vB;
if(*index>0&&*(strFangcheng.begin()+(*index-1))=='-')
m_vB=-m_vB;
}else m_vB=1;
}
}
}
}
std::cout<<"解析结果:a="<<m_vA<<"   b="<<m_vB<<"   c="<<m_vC<<std::endl;
}


// yiyuanerci.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "fangcheng.h"

int _tmain(int argc, _TCHAR* argv[])
{
fangcheng fc1;
fc1.jie();
fc1.print();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐