【解题报告】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 ...
随机推荐
- 妙味课堂——HTML+CSS(第四课)(二)
单开一篇来讲一个大点的话题——清浮动 来看下例: <!DOCTYPE html> <html> <head> <meta charset="U ...
- GET和POST测试(支持需要登录的接口调用:高级功能->填写cookie)
http://coolaf.com
- java基本数据类型存储范围
数据类型可以分为两大类: 1)基本类型: 2)扩展类型. 先来看一下Java语言的基本数据类型.它包括 类型 描述 取值范围 Boolean 布尔型 只有两个值true.false Char ...
- 解决IIS应用程序池DefaultAppPool关闭超时错误
错误系统日志: 为应用程序池“DefaultAppPool”提供服务的进程关闭时间超过了限制.进程 ID 是“3060”. 有关更多信息,请参阅在http://go.microsoft.com/fwl ...
- Linux系统下如何禁止ping命令或允许ping命令的方法
1.禁止pingecho 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all 2.允许ping echo 0 >/proc/sys/net/ipv4/ic ...
- CentOS7-64bit 编译 Hadoop-2.5.0,并分布式安装
摘要 CentOS7-64bit 编译 Hadoop-2.5.0,并分布式安装 目录[-] 1.系统环境说明 2.安装前的准备工作 2.1 关闭防火墙 2.2 检查ssh安装情况,如果没有则安装ssh ...
- word2010中怎样快速修改同级标题格式
我要把所有三级目录的字体增大,怎样能一次选中批量修改?文章很长,一百多个三级标题.word 2010中提供了快速修改的方法: ①将光标定位在一个三级标题中② <IGNORE_JS_OP> ...
- Spring Boot Servlet
上一篇我们对如何创建Controller 来响应JSON 以及如何显示数据到页面中,已经有了初步的了解. Web开发使用 Controller 基本上可以完成大部分需求,但是我们还可能会用到 Serv ...
- gearman安装及初次使用
官网: http://gearman.org/ 一篇文章: 利用Gearman实现异步任务处理 一.问题分析 问题:在性能测试过程中,发现用户管理平台在进行图片上传时,性能不佳. 分析:经过代码分析 ...
- Win XP 如何禁用屏保
如果你试过 “在桌面空白处点击右键-[属性]-[屏幕保护程序],选择[无],点击[确定]”后,当时是可以去掉屏保.但如果重启计算机或者从待机状态唤醒后,屏保依然会出现,那么你可以试试下面的方法. 首先 ...