上交大 2011 二次方程计算器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了上交大 2011 二次方程计算器相关的知识,希望对你有一定的参考价值。
题目:
输入关于x的二次方程表达式(系数为整数),输出两个解(由小到大输出,保留两位小数);如果无解,则输出“No Solution”。
思路:
先确定等号位置,分成左右两个字符串,从中分别提取系数,再综合。然后求解。
提取系数的过程如图:
过程:
介绍两个函数:
atoi()函数可以识别"+""-"号,并正确转化成int。
string str="-2980"; string s="+12"; cout<<atoi(str.c_str())<<endl; cout<<atoi(s.c_str())<<endl;
substr(int begin,int len)函数表示截取从begin开始的长尾len的string返回(若没第二个参数,则取到尾)。
string str="Ihaveapen!"; string s=str.substr(2,5);
此次调试用了很久:
现象为:遇到questXishu()函数,调试就卡在那里,运行也是(出不来结果,也程序也一直没结束)。OJ显示"Time Limit Exceed"。
后来才发现不是函数卡住,而是一直在运行,而且在死循环(判断二次项时,str[i+1]==‘^‘不小心写成str[i]==‘^‘)。
代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string> 4 #include <cstring> 5 #include <cstdlib> 6 #include <cmath> 7 using namespace std; 8 9 //求取等式的系数。str为式子,系数提取到a数组 10 void questXishu(string str,int *a); 11 12 int main(){ 13 string str; //str:式子,s:数字字串 14 string sL,sR; //等号左右字串 15 int len,i; //式子长度 16 int xiShuL[3],xiShuR[3],deTa; //分别为常数,一次,二次的系数 17 double x1,x2; //解 18 19 while(cin>>str){ //输入式子 20 memset(xiShuL,0,3*sizeof(int)); //系数数组清空 21 memset(xiShuR,0,3*sizeof(int)); //系数数组清空 22 len=str.length(); //字符串长度 23 for(i=0;i<len;i++){ //找到等号位置 24 if(str[i]==‘=‘) 25 break; 26 } 27 sL=str.substr(0,i); //截取等号左右字串 28 sR=str.substr(i+1); 29 30 31 questXishu(sL,xiShuL); //求取左右式的系数 32 questXishu(sR,xiShuR); 33 34 xiShuL[0]=xiShuL[0]-xiShuR[0]; //计算最终系数 35 xiShuL[1]=xiShuL[1]-xiShuR[1]; 36 xiShuL[2]=xiShuL[2]-xiShuR[2]; 37 //计算并输出解 38 if((deTa=(xiShuL[1]*xiShuL[1]-4*xiShuL[2]*xiShuL[0]))>=0){ 39 x1=(-xiShuL[1]-sqrt(deTa/1.0))/(2.0*xiShuL[2]); 40 x2=(-xiShuL[1]+sqrt(deTa/1.0))/(2.0*xiShuL[2]); 41 if(x1>x2) 42 printf("%.2lf %.2lf\\n",x2,x1); 43 else 44 printf("%.2lf %.2lf\\n",x1,x2); 45 } 46 else 47 printf("No Solution\\n"); 48 } 49 return 0; 50 } 51 52 //求取等式的系数。str为式子,系数提取到a数组 53 void questXishu(string str,int *a){ 54 int len=str.length(),i=0; 55 string s=""; //用来放系数串 56 while(i<len){ //遍历 57 if(str[i]==‘+‘ || str[i]==‘-‘){ //遇到+/-号:后面一定跟着系数 58 //常数项要么:1.后面跟着+/-号,2.要么放在串最后 59 if(s!=""){ //此处是情况1:常数项后跟着+/-号。若有常数项未处理,则处理下常数项 60 a[0]+=atoi(s.c_str()); //加入常数项系数 61 s=""; //s恢复为空 62 } 63 s+=str[i]; //记下符号 64 i++; 65 continue; 66 } 67 //遇到数字:为系数,记录下来 68 while(i<len && ‘0‘<=str[i] && str[i]<=‘9‘){ 69 s+=str[i]; 70 i++; 71 } 72 if(i>=len) //从数字循环退出原因若为i>len,则str遍历结束,退出 73 break; 74 75 if(str[i]==‘x‘){ //遇到字符x 76 if((i+1)<len && str[i+1]==‘^‘){ //还有下一位,且为^:二次项 77 if(s=="" || s=="+") //处理系数为+/-1的情况 78 s="1"; 79 else{ 80 if(s=="-") 81 s="-1"; 82 } 83 a[2]+=atoi(s.c_str()); //数字加入二次项系数 84 s=""; //s恢复为空 85 i=i+3; //跳到下下下位 86 } 87 else{ //其他情况:一次项 88 if(s=="" || s=="+") //处理系数为+/-1的情况 89 s="1"; 90 else{ 91 if(s=="-") 92 s="-1"; 93 } 94 a[1]+=atoi(s.c_str()); //数字加入一次项系数 95 s=""; //s恢复为空 96 i=i+1; //跳到下位 97 } 98 } 99 } 100 if(s!=""){ //常数项情况2:放在串最后。循环内未来得及处理。 101 a[0]+=atoi(s.c_str()); 102 } 103 }
以上是关于上交大 2011 二次方程计算器的主要内容,如果未能解决你的问题,请参考以下文章