NOIP2000普及组 计算器的改良 Codevs1015 字符串复杂处理
2016-06-29 23:57
344 查看
http://codevs.cn/problem/1015/
题目大意:输入一个字符串,是一个一元一次方程。该方程只有整数、‘+’、‘-’、‘=’ 三个符号,其中‘-’既可以是负号也可以是减号。没有乘除号、括号和小数。常数和未知数之间的相乘,省略乘号或‘·’。要求输出方程的根,保留三位小数。
输入保证该方程合法,有且仅有一个实根。
样例输入 Sample Input
6a-5+1=2-2a
样例输出 Sample Output
a=0.750
大致思路:先确定代表未知数的字母。然后从左到右逐个字符进行讨论。分别存储常数项的和,以及未知数项的系数之和。在等号右边时,移项过后加变减,减变加。
处理较为繁杂,需细心考虑。
直接给出代码。(加了注释之后代码看起来很长。只是看起来)
#include<string>
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
string s;
char x;<span style="white-space:pre"> </span>//表示未知数的字母
double dx=0,dk=0; //dx记录未知数的各项系数之和,dy记录所有常数项之和
bool is_alpha(char c) //判断某个字符是不是字母
{if ((c>='a' && c<='z')||(c>='A' && c<='Z')) return true; return false;}
bool is_num(char c) //判断某个字符是不是数字
{if (c>='0' && c<='9') return true; return false;}
void calc(int f,int sum,bool l,double &add){ //add 采用引用的形式,就不需要讨论加的是dx还是dk了
//f表示当前项正负,sum表示当前项常数之和,l表示在等号左边还是右边
if (l==1) add+=sum*f; //如果在等号左边,正常做加减
if (l==0) add-=sum*f; //如果在等号右边,由于移项,加变减,减变加
}
int main(){
cin>>s;
//确认代表未知数的字母
for (int i=0;i<s.length();i++)
if (is_alpha(s[i])) {
x=s[i];break;
}
bool l=1; //1表示在等号左边 , 0表示在等号右边
int f=1; //1表示当前项为正 , -1表示当前项为负
int sum=0; //当前项的常数值
for (int i=0;i<=s.length();i++){ //取等号是因为把所有字符都讨论完了之后还要再运算一次
if (i==s.length()) {calc(f,sum,l,dk); break;} //如上一行注释所说,如果是最后一次,只做运算,不讨论字符
char c=s[i];
//以下每行都写continue是为了整齐一点,不用写else
//如果是+或者-,之前必定已有一项结束,故先对之前一项进行计算,然后重置f和sum
if (c=='-') {calc(f,sum,l,dk); f=-1,sum=0; continue;}
if (c=='+') {calc(f,sum,l,dk); f= 1,sum=0; continue;}
/*如果是未知数,分两种情况:当sum=0时,意味着这个未知数项没有系数,要将系数修正为1;(数据里没有0x这样的项)
当sum!=0时,正常做加减即可。记得计算完之后修正f和sum。这样即使后面跟+或-,对常数的加减也是0,没有影响*/
if (c== x ) {if (sum==0) sum=1; calc(f,sum,l,dx); f= 1,sum=0; continue;}
//如果是数字,加sum就好了
if (is_num(c)) {sum*=10; sum+=c-'0'; continue;}
//碰到等号,修改l的值。不要忘了先进行一次计算
if (c=='=') {calc(f,sum,l,dk); l=0,f=1,sum=0; continue;}
}
printf("%c=%.3lf",x,-dk/dx); //由于以上的操作把常数项和未知数项都放在等号左边,所以求解时要加负号
return 0;
}
题目大意:输入一个字符串,是一个一元一次方程。该方程只有整数、‘+’、‘-’、‘=’ 三个符号,其中‘-’既可以是负号也可以是减号。没有乘除号、括号和小数。常数和未知数之间的相乘,省略乘号或‘·’。要求输出方程的根,保留三位小数。
输入保证该方程合法,有且仅有一个实根。
样例输入 Sample Input
6a-5+1=2-2a
样例输出 Sample Output
a=0.750
大致思路:先确定代表未知数的字母。然后从左到右逐个字符进行讨论。分别存储常数项的和,以及未知数项的系数之和。在等号右边时,移项过后加变减,减变加。
处理较为繁杂,需细心考虑。
直接给出代码。(加了注释之后代码看起来很长。只是看起来)
#include<string>
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
string s;
char x;<span style="white-space:pre"> </span>//表示未知数的字母
double dx=0,dk=0; //dx记录未知数的各项系数之和,dy记录所有常数项之和
bool is_alpha(char c) //判断某个字符是不是字母
{if ((c>='a' && c<='z')||(c>='A' && c<='Z')) return true; return false;}
bool is_num(char c) //判断某个字符是不是数字
{if (c>='0' && c<='9') return true; return false;}
void calc(int f,int sum,bool l,double &add){ //add 采用引用的形式,就不需要讨论加的是dx还是dk了
//f表示当前项正负,sum表示当前项常数之和,l表示在等号左边还是右边
if (l==1) add+=sum*f; //如果在等号左边,正常做加减
if (l==0) add-=sum*f; //如果在等号右边,由于移项,加变减,减变加
}
int main(){
cin>>s;
//确认代表未知数的字母
for (int i=0;i<s.length();i++)
if (is_alpha(s[i])) {
x=s[i];break;
}
bool l=1; //1表示在等号左边 , 0表示在等号右边
int f=1; //1表示当前项为正 , -1表示当前项为负
int sum=0; //当前项的常数值
for (int i=0;i<=s.length();i++){ //取等号是因为把所有字符都讨论完了之后还要再运算一次
if (i==s.length()) {calc(f,sum,l,dk); break;} //如上一行注释所说,如果是最后一次,只做运算,不讨论字符
char c=s[i];
//以下每行都写continue是为了整齐一点,不用写else
//如果是+或者-,之前必定已有一项结束,故先对之前一项进行计算,然后重置f和sum
if (c=='-') {calc(f,sum,l,dk); f=-1,sum=0; continue;}
if (c=='+') {calc(f,sum,l,dk); f= 1,sum=0; continue;}
/*如果是未知数,分两种情况:当sum=0时,意味着这个未知数项没有系数,要将系数修正为1;(数据里没有0x这样的项)
当sum!=0时,正常做加减即可。记得计算完之后修正f和sum。这样即使后面跟+或-,对常数的加减也是0,没有影响*/
if (c== x ) {if (sum==0) sum=1; calc(f,sum,l,dx); f= 1,sum=0; continue;}
//如果是数字,加sum就好了
if (is_num(c)) {sum*=10; sum+=c-'0'; continue;}
//碰到等号,修改l的值。不要忘了先进行一次计算
if (c=='=') {calc(f,sum,l,dk); l=0,f=1,sum=0; continue;}
}
printf("%c=%.3lf",x,-dk/dx); //由于以上的操作把常数项和未知数项都放在等号左边,所以求解时要加负号
return 0;
}
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 数据库链接字符串查询网站
- 如何写好 C main 函数
- Flex字符串比较 还有Flex字符串操作
- Ruby中创建字符串的一些技巧小结
- ASP下经常用的字符串等函数参考资料
- 将字符串小写转大写并延时输出的批处理代码
- 将字符串转换成System.Drawing.Color类型的方法
- BAT批处理中的字符串处理详解(字符串截取)
- Lua和C语言的交互详解
- Lua源码中字符串类型的实现
- Lua函数与字符串处理简明总结
- Lua性能优化技巧(四):关于字符串
- 字符串聚合函数(去除重复值)
- Ruby中的字符串编写示例
- 总结的5个C#字符串操作方法分享
- sqlserver中求字符串中汉字的个数的sql语句
- sql server字符串非空判断实现方法
- C#算法函数:获取一个字符串中的最大长度的数字
- VBS的字符串及日期操作相关函数