ZOJ 1138 Symbolic Derivation



Symbolic Derivation

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) :    Accepted Submission(s) : 
Problem Description
Write a program that performs symbolic derivation f锟斤拷(x) = df(x)/dx of a given function f(x). The function f(x) is defined by an expression which may contain the following operations: + (addition), - (subtraction), * (multiplication), / (division), and ln (natural logarithm). Besides, the operands may be the variable x and numerical constants. The expression may contain arbitrarily nested sub-expressions in parentheses ( ). The expression is given in a usual, infix form, such as:

(2*ln(x+1.7)-x*x)/((-7)+3.2*x*x)+(x+3*x)*x

Numerical constants have the form d.d, with an optional sign (+ or -), where the number of digits both in integer and decimal parts are arbitrary. The input expression is guaranteed to be correct (no syntax error can occur).

The output expression should be written in infix form. It should not be optimized for human reading. This means, it can contain redundancies, such as 0*x, 1*x, 0+x, etc. The derivation should be performed using the following rules:

1. The operators * and / are of higher priority than the operators + and -. Parentheses may change the priorities as usually.

2. The operators +, -, *, and / are left-associative, meaning that they group from left to right: a*b*c = (a*b)*c, a/b/c = (a/b)/c, a/b*c = (a/b)*c, etc.

3. The rules for derivation are:
(a + b)' = a' + b'
(a - b)' = a' - b'
(a * b)' = (a' * b + a * b')
(a / b)' = (a' * b - a * b') / b^2 Note: use b^2 and not (b*b) for presentation
ln(a)' = (a')/(a)
x' = 1
const' = 0

4. While producing the symbolic derivation, use parentheses for output strictly as stated in the previous rule. Do not perform presentation optimizations, such as 0*a = 0, 1*a = a, etc.

The input has one f(x) definition per line. The input lines do not have blanks. The output should contain lines with corresponding symbolic derivations f锟斤拷=df/dx, one line for each f. The strings representing f(x) and f 锟斤拷(x) are guaranteed to have no more than 100 characters.

Sample input and output:


Input

x*x/x
-45.78*x+x 
-2.45*x*x+ln(x-3)


Output

((1*x+x*1)*x-x*x*1)/x^2 
(0*x-45.78*1)+1 
((0*x-2.45*1)*x-2.45*x*1)+(1-0)/(x-3) 

 

Source
Southeastern Europe 2000
 


#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>

using namespace std;

int pri[256];
string str;

string chao(string s)
{
    int loc=-1; int lp=0;
    char w='\0';

    ///part one    找优先级最低的运算符
    for(int i=s.size()-1;i>=0;i--)
    {
        switch(s )
        {
        case')':
            lp++; break;
        case'(':
            lp--; break;
        case'+':case'-':
            if(i&&((s[i-1]>='0'&&s[i-1]<='9')||s[i-1]=='x'))
            {
                if(lp==0&&(loc==-1||pri[s ]<pri[w]))
                {
                    loc=i;
                    w=s ;
                }
            }
            break;
        case'*':case'/':
            if(lp==0&&(loc==-1||pri[s ]<pri[w]))
            {
                loc=i;
                w=s ;
            }
            break;
        case'n':
            i--;
            if(lp==0&&(loc==-1||pri[s ]<pri[w]))
            {
                loc=i;
                w=s ;
            }
            break;
        }
    }

//cout<<"---->  "<<s<<endl;
    ///patr two   递归输出
    string a,b;
    switch(w)
    {
    case'+':case'-':
        return chao(s.substr(0,loc))+w+chao(s.substr(loc+1,s.size()-loc-1));
        break;
    case'*':
        a=s.substr(0,loc); b=s.substr(loc+1,s.size()-loc-1);
        return "("+chao(a)+"*"+b+"+"+a+"*"+chao(b)+")";
        break;
    case'/':
        a=s.substr(0,loc); b=s.substr(loc+1,s.size()-loc-1);
        return "("+chao(a)+"*"+b+"-"+a+"*"+chao(b)+")/"+b+"^2";
        break;
    case'l':
        a=s.substr(3,s.size()-4);
        return "("+chao(a)+")/("+a+")";
        break;
    default:
        if(s[0]=='(')
        {
            return "("+chao(s.substr(1,s.size()-2))+")";
        }
        else
        {
        if(s[0]=='x')
            return "1";
        else
            return "0";
        }
    }
}

int main()
{
    pri['+']=pri['-']=1;
    pri['*']=pri['/']=2;
    pri['l']=3;
    string pre;
while(cin>>pre)
{
   string str2=chao(pre);

   int len=str2.size();
   for(int i=0;i<len;i++)
   {
       if(str2 =='+'||str2=='-')
       {
           if(str2[i+1]=='+'||str2[i+1]=='-')
           {
               if(str2 ==str2[i+1])
               {
                   putchar('+');
                   i++;
               }
               else
               {
                   putchar('-');
                   i++;
               }
           }
           else
           putchar(str2 );
       }
       else putchar(str2 );
   }
   putchar(10);
}
    return 0;
}

转载于:https://www.cnblogs.com/CKboss/p/3350977.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值