上交大 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 二次方程计算器的主要内容,如果未能解决你的问题,请参考以下文章

清华北大上交大哈工大中山大学5位同学眼中的开源

Texygen文本生成,交大计算机系14级的朱耀明

上海交大牵手淘宝成立媒体计算实验室:推动视频超分等关键技术发展

交大博士学长:研究生计算机专业的方向选择!

操作系统--交大第三套

从片段着色器中的地形高程数据计算法线