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

来源:互联网 发布:阿里云os 魅族 编辑:程序博客网 时间:2024/06/04 08:22

显然在这个题目中,如何解析输入的字符创是主要问题,我的思路是用'+',‘-’,‘=’分段这个字符串,并将每段的开头用一个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;// 一元二次方程的adouble m_vB;// 一元二次方程的bdouble m_vC;// 一元二次方程的cdouble 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);//以每个元素为一段的开头,故除了关键点外需要手动添加0int 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();elsetheEnd=*(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;}


原创粉丝点击