【解题报告】POJ-1467 Symbolic Derivation
原题地址:http://poj.org/problem?id=1467
题目大意:
对一个式子求导,给的式子包括常量,字母x,+,-,*,/,ln()运算符,任意嵌套的括号。求的导数式子不用化简,如1*x这样的式子不用变成x。下面给出了一些求导规则和运算优先级:
1.乘除的优先级大于加减。
2.同优先级结合性从左往右。
3. 求导规则:
(a + b)' = a' + b'
(a - b)' = a' - b'
(a * b)' = (a' * b + a * b')
(a / b)' = (a' * b - a * b') / b^2 Note: 写 b^2 而不是 (b*b)
ln(a)' = (a')/(a)
x' = 1
常数的导数 = 0
要注意的是,如上所给的规则中,有括号的部分要在求导式子中相应的加上括号。如:
输入1*1
输出(0*1+1*0)
这里的括号不能去掉。
解题思路:
将整个式子当做一个字符串来处理。
如果这个字符串是一个数字,则求导结果是 0
如果这个字符串是一个x,则求导结果是 1
否则,找到最后计算的那一个运算符(这个字符不能在任何括号里),如:" (2*ln(x+1.7)-x*x)/((-7)+3.2*x*x)+(x+3*x)*x "中,先最后计算的运算符是红色的加号。然后以这个加号为分界点,将整个式子分解成两部分,“ (2*ln(x+1.7)-x*x)/((-7)+3.2*x*x) ” 和“(x+3*x)*x” 然后根据加法求导法则,分别求两部分的导数,则将两部分分别递归一遍。
若没有找到上一条所述的运算符(即整个字符串包含在括号里,或者为ln运算)
如果是整个括号包含的字符串,则去掉这个括号得到的字符串递归一遍。
如果是ln()运算符,则根据ln()求导法则递归。
解题代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stack>
using namespace std;
class String
{
public:
char s[];
String(){s[]=;}
String(String& s1){strcpy(s,s1.s);}
bool isnum();
};
char ans[];
ostream& operator<<(ostream& out,String &s1)
{
cout<<s1.s;
return out;
}
bool String::isnum()
{
int i=;
if(s[]=='-') i++;
for(;s[i];i++)
{
if(s[i]=='.'||(s[i]>=''&&s[i]<='')) ;
else break;
}
if(!s[i]) return true;
else return false;
}
void qiudao(String s1);
void jia(String s1,String s2)
{
qiudao(s1);
strcat(ans,"+");
qiudao(s2);
}
void jian(String s1,String s2)
{
qiudao(s1);
strcat(ans,"-");
qiudao(s2);
}
void cheng(String s1,String s2)
{
strcat(ans,"(");
qiudao(s1);
strcat(ans,"*");
strcat(ans,s2.s);
strcat(ans,"+");
strcat(ans,s1.s);
strcat(ans,"*");
qiudao(s2);
strcat(ans,")");
}
void chu(String s1,String s2)
{
strcat(ans,"(");
qiudao(s1);
strcat(ans,"*");
strcat(ans,s2.s);
strcat(ans,"-");
strcat(ans,s1.s);
strcat(ans,"*");
qiudao(s2);
strcat(ans,")/");
strcat(ans,s2.s);
strcat(ans,"^2");
}
void ln(String s1)
{
strcat(ans,"(");
qiudao(s1);
strcat(ans,")/(");
strcat(ans,s1.s);
strcat(ans,")");
}
void qiudao(String s1)
{
int i;
if(s1.isnum()) {strcat(ans,"");return ;}//如果字符串表示一个数字,则求导结果为 0
if(strcmp(s1.s,"x")==) {strcat(ans,"");return ;}//如果字符串是一个x,则求导结果为 1
int len=strlen(s1.s);
//下面用于计算优先级最低的一个运算符。
int n=-,you=;
for(i=;s1.s[i];i++)
{
if(i!=&&((s1.s[i]=='+'||s1.s[i]=='-')&&you>=)) {n=i;you=;break;}
if(i!=&&((s1.s[i]=='*'||s1.s[i]=='/')&&you>=)) {n=i;you=;}
if(s1.s[i]=='(')
{
int n=;
while(n)
{
i++;
if(s1.s[i]=='(')n++;
if(s1.s[i]==')')n--;
}
}
}
if(you!=)
{
String ss1,ss2;
strncpy(ss1.s,s1.s,n);
ss1.s[n]=;
strncpy(ss2.s,&s1.s[n+],len-n-);
ss2.s[len-n-]=;
switch(s1.s[n])
{
case '+':jia(ss1,ss2);break;
case '-':jian(ss1,ss2);break;
case '*':cheng(ss1,ss2);break;
case '/':chu(ss1,ss2);break;
}
return ;
}
if(s1.s[]=='('&&s1.s[len-]==')')
{
String s2;
strncpy(s2.s,s1.s+,len-);
s2.s[len-]=;
strcat(ans,"(");
qiudao(s2);
strcat(ans,")");
return ;
}
if(strncmp(s1.s,"ln(",)==&&s1.s[len-]==')')
{
String ss1;
strncpy(ss1.s,s1.s+,len-);
ss1.s[len-]=;
ln(ss1);
}
}
int main()
{
String s1;
int i;
while(cin>>s1.s)
{
ans[]=;
qiudao(s1);
for(i=;ans[i];i++)
{
if(ans[i+]=='-')
{
if(ans[i]=='+') {cout<<'-';i++;continue;}
if(ans[i]=='-') {cout<<'+';i++;continue;}
}
cout<<ans[i];
}
cout<<endl;
}
return ;
}
【解题报告】POJ-1467 Symbolic Derivation的更多相关文章
- POJ 1001 解题报告 高精度大整数乘法模版
题目是POJ1001 Exponentiation 虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...
- POJ 2002 Squares 解题报告(哈希 开放寻址 & 链式)
经典好题. 题意是要我们找出所有的正方形.1000点,只有枚举咯. 如图,如果我们知道了正方形A,B的坐标,便可以推测出C,D两点的坐标.反之,遍历所有点作为A,B点,看C,D点是否存在.存在的话正方 ...
- Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)
http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何 ...
- 【九度OJ】题目1467:二叉排序树 解题报告
[九度OJ]题目1467:二叉排序树 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1467 题目描述: 二叉排序树,也称为二叉查找树 ...
- POJ 3126 Prime Path 解题报告(BFS & 双向BFS)
题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...
- poj分类解题报告索引
图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Jou ...
- POJ 2054 Color a Tree解题报告
题干 Bob is very interested in the data structure of a tree. A tree is a directed graph in which a spe ...
- poj1173 解题报告
poj1173 解题报告2013-07-21 13:31 by 期待 ., 42 阅读, 0 评论, 收藏, 编辑 http://poj.org/problem?id=1173 发现此题资料甚少,斗胆 ...
- ACM-ICPC 2017 Asia HongKong 解题报告
ACM-ICPC 2017 Asia HongKong 解题报告 任意门:https://nanti.jisuanke.com/?kw=ACM-ICPC%202017%20Asia%20HongKon ...
随机推荐
- DMS平台从.NET 1.1升级到.NET 4.0的升级步骤
1)复制新增的项目到4.0平台解决方案对应目录,添加到到解决方案中:2)合并公共文件(比如修改了FormMain主界面.基础类库.售后界面的修改)3)控件的修订(Dev少数属性可能需要手工调整为新的方 ...
- [你必须知道的.NET]第三十一回,深入.NET 4.0之,从“新”展望
发布日期:2009.05.22 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. /// <summary> /// 本文开始,将以& ...
- hdu 3118(二进制枚举)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3118 思路:题目要求是去掉最少的边使得图中不存在路径长度为奇数的环,这个问题等价于在图中去掉若干条边, ...
- Hadoop 在windows 上伪分布式的安装过程
第一部分:Hadoop 在windows 上伪分布式的安装过程 安装JDK 1.下载JDK http://www.oracle.com/technetwork/java/javaee/d ...
- delphi中的Label控件背景透明
Label1.Transparent:=true;你在它的属性窗口把它的Transparent属性改成TRUE就行了 来自为知笔记(Wiz)
- CentOS 7:如何安装防火墙?
对于纯净版的CentOS 7,您必须手动安装防火墙.但是你就算安装了防火墙还是不能马上运行它,你需要再做一些操作才能让它工作. 在CentOS 7中按照以下步骤来设置防火墙 第一步,通过yum安装sy ...
- Jenkins Master/Slave架构
原文:http://www.cnblogs.com/itech/archive/2011/11/11/2245849.html 一 Jenkins Master/Slave架构 Master/Slav ...
- android 广播的使用
在Activity中,注册广播的一个Demo. 总共分3步 第一步:定义一个BroadcastReceiver广播接收类: private BroadcastReceiver mBroadcastRe ...
- 蓝牙接收苹果手机通知 ANCS协议分析
蓝牙接收苹果手机通知 ANCS协议分析 转载,请注明出处:http://www.cnblogs.com/alexcai/p/4321514.html 综述 现在有许多蓝牙手表.手环都能接收苹果ipho ...
- blade全集
http://daylerees.com/codebright/blade