题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=138
题意:给一个关于x的函数表达式包含+,-,*,/四种运算还有括号,按要求格式输出其导数
分析:表达式不长所以这明显是模拟,而且要递归的搞。再看看这题的难点:①有负数如:-2.0②有括号③乘除是从左到右算。对于这三点可以想到一下做法①只对最小元(常数和x)求导②括号要整体处理,当括号是最小元时保存括号,递归处理括号中间点内容③由于负数情况太多,所以在所有其他可能最小元情况判断后直接返回‘0’。想到这些就可以搞了。
PS:这题为练代码。。一下没考虑全码了一晚上。。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#define inf 1<<31-1
using namespace std;
string s;
string dfs(int l,int r)
{
//cout<<l<<' '<<r<<endl;
//cout<<s.substr(l,r-l+1)<<endl;
if(l>=s.size()||r<l)return string("");
for(int i=r;i>=l;i--)
{
if(s[i]==')')
{
int j=i,t=0;
for(;j>=l;j--)
{
if(s[j]=='(')t--;
if(s[j]==')')t++;
if(t==0)break;
}
if(j>1&&s[j-2]=='l'&&s[j-1]=='n')i=j-3;
else i=j-1;
}
if(i<l)break;
if(i==l&&(s[i]=='+'||s[i]=='-'))continue;
if(s[i]=='-'||s[i]=='+')
{
string tl=dfs(l,i-1);
string tr=dfs(i+1,r);
char tem=s[i];
if(tr[0]=='-')
{
if(s[i]=='+')tem='\0';
else{tem='+';tr.erase(tr.begin());}
}
return tl+tem+tr;
}
}
for(int i=r;i>=l;i--)
{
if(s[i]==')')
{
int j=i,t=0;
for(;j>=l;j--)
{
if(s[j]=='(')t--;
if(s[j]==')')t++;
if(t==0)break;
}
if(j>1&&s[j-2]=='l'&&s[j-1]=='n')i=j-3;
else i=j-1;
}
if(i<l)break;
if(s[i]=='*')
{
string tl=dfs(l,i-1);
string tr=dfs(i+1,r);
string sl=s.substr(l,i-l);
string sr=s.substr(i+1,r-i);
if(sl[0]=='-')return '('+tl+'*'+sr+sl+'*'+tr+')';
return '('+tl+'*'+sr+'+'+sl+'*'+tr+')';
}
else if(s[i]=='/')
{
string tl=dfs(l,i-1);
string tr=dfs(i+1,r);
string sl=s.substr(l,i-l);
string sr=s.substr(i+1,r-i);
char tem='-';
if(sl[0]=='-'){tem='+';sl.erase(sl.begin());}
return '('+tl+'*'+sr+tem+sl+'*'+tr+')'+'/'+sr+"^2";
}
}
if(l==r&&s[l]=='x')return string("1");
else if(s[l]=='('&&s[r]==')')
{
return '('+dfs(l+1,r-1)+')';
}
else if(s[l]=='l'&&s[l+1]=='n')
{
return '('+dfs(l+3,r-1)+")/"+'('+s.substr(l+3,r-l-3)+')';
}
else
{
return string("0");
}
}
int main()
{
int cas=1;
while(cin>>s)
{
//printf("Case %d:",cas++);
cout<<dfs(0,s.size()-1)<<endl;
}
return 0;
}