【解题报告】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 ...
随机推荐
- Android中两种设置全屏的方法
设置全屏的两种方法: 第一种:在配置文件里面配置: <?xml version="1.0" encoding="utf-8"?><manife ...
- MongoDB (三) MongoDB 安装
MongoDB安装在Windows上 在 Windows上,首先要安装 MongoDB下载最新发布的MongoDB: http://www.mongodb.org/downloads 确保得到正确的版 ...
- http://www.cnblogs.com/TankXiao/p/4018219.html
http://www.cnblogs.com/TankXiao/p/4018219.html
- SVN的使用(转载)
MyEclipse中的SVN操作手册 导入项目 点击工具栏中的File-Import,进入下图: 点击Nex进入下图: 点击Next进入下图,输入你SVN服务器的IP地址,包括端口号和文件夹等完整 ...
- Android百度地图开发02之添加覆盖物 + 地理编码和反地理编码
下面来看一下地图上覆盖物的添加,以及地理编码和反地理编码. 添加覆盖物 在地图上添加覆盖物,一般需要以下几个步骤: 1. 定义坐标点,有可能是一个,有可能是多个(比如:多边形覆盖物). 2. 构造Ov ...
- 唯一区别是不会去取emptyText 的值,没有选选择选项的时候返回是空字符串
combox取值以及赋值的方法 function getValue() { //注意:以下这两种取值方法都会存在一个问题: 当combox设置成能输入并有只能提示的时候,当输入的不是备选项时,或到的v ...
- PCA基础理解
- javascript 阻止冒泡
JS 阻止冒泡 function stopBubble(e) { //如果提供了事件对象,则这是一个非IE浏览器 if(e && e.stopPropagation) { //因此它 ...
- guice的基本使用(一)
guice是google一个轻量级的DI注入框架,现在比较强大了,也与目前流行的struts2.jpa等都有集成了. 先看一个例子: package com.ming.user.test; publi ...
- MySQL:创建、修改和删除表
其实对很多人来说对于SQL语句已经忘了很多,或者说是不懂很多,因为有数据库图形操作软件,方便了大家,但是我们不能忘记最根本的东西,特别是一些细节上的东西,可能你用惯了Hibernate,不用写SQL语 ...