zoukankan      html  css  js  c++  java
  • 蓝桥杯---公式解析


    在某些应用中,为了支持灵活性,往往用到自定义的公式。

    比如,有如下的原始公式集合:

        int add(int x, int y):  返回x与y的和
        
        int add(int x, int y, int z):  返回x,y,z三个数的和
        
        int min(int x, int y):  返回x,y中较小的值
        
        int max(int x, int y):  返回x,y中较大的值

        int doubleMe(int x):  返回 x 的2倍

    给出一个自定义公式串

    add(min(5,3),max(2,8),add(1,doubleMe(1)))

    通过手工计算可以得出结果为:14

    本题的任务是:编写一个解析程序,能够对由上述原始公式任意组合出来的公式计算其结果。也就是输入一个自定义公式串,输出它的计算结果(可以不考虑输入公式本身有语法错误的情况)。

    输入的公式串中可以含有多余的空格,类似:

    add( min(5, 3) , max(2 , 8) )  也是合法的公式。

    程序输入:公式串
    程序输出:该公式的计算值




    解题思路:思路相对来说比较简单,以前做过好几道这样的题目,但是这是第一次完全自己写的,其实就是用递归的思路,不过要做递归,思路一定是需要清晰的,否则在递归的时候很容易出错,并且出了错还是不好查找的,另外的一个重要的事情就是必须要设定好正确的递归出口,深切体验。。。


    具体思路,在每一次的时候都是从第一个字母开始搜索,当遇到关键的字眼,也就是add、min、max、doubleMe的时候就就开始分割,直到出现的左括号‘(’的数目和右括号‘)’的数目相同,并且出现了部分的结束标志,也就是再一个’)‘或者是’,‘,这样的话就把每一部分分解开了,但是这样的话代码好像就不太美观了,有点长。。。

    #include <iostream>
    #include <cstdio>
    #include <memory.h>
    using namespace std;
    int count(string str){
        int len = str.length();
    	if(str[0]<='9'&&str[0]>='0'){
    	  int temp=0,i=0;
    	  temp=str[i++]-'0';
    	  while(i<len&&str[i]<='9'&&str[i]>='0'){
    	   temp=temp*10+str[i]-'0';
    	   i++;
    	   }
    	  return temp;
    	}
    	if(str[0]=='a'){
    	   int i=4,templ=0,tempr=0,tmp=0;
    	   for(int x=1;x<=3&&i<len;x++,i++){
    	   	 string s="";
    	     while(   templ!=tempr|| (  str[i]!=',' && str[i]!=')'    )      ){
    	   	 if(str[i]=='(') templ++;
    	   	 if(str[i]==')') tempr++;
    	   	 s+=str[i];
    	     i++;
    	   }
    	   tmp+=count(s);
    	   }
    	  return tmp;
    	}
    	if(str[0]=='m'&&str[1]=='i'){
    	   int i=4,templ=0,tempr=0,tmp1=0,tmp2=0;
    	   for(int x=1;x<=2&&i<len;x++,i++){
    	   	 string s="";
    	     while(   templ!=tempr|| (  str[i]!=',' && str[i]!=')'    )      ){
    	   	 if(str[i]=='(') templ++;
    	   	 if(str[i]==')') tempr++;
    	   	 s+=str[i];
    	     i++;
    	    }
    	   x==1?tmp1=count(s):tmp2=count(s);
    	   }
    	  return tmp1<tmp2?tmp1:tmp2;
    	}
    	if(str[0]=='m'&&str[1]=='a'){
    	   int i=4,templ=0,tempr=0,tmp1=0,tmp2=0;
    	   for(int x=1;x<=2&&i<len;x++,i++){
    	   	 string s="";
    	     while(   templ!=tempr|| (  str[i]!=',' && str[i]!=')'    )      ){
    	   	 if(str[i]=='(') templ++;
    	   	 if(str[i]==')') tempr++;
    	   	 s+=str[i];
    	     i++;
    	    }
    	   x==1?tmp1=count(s):tmp2=count(s);
    	   }
    	  return tmp1>tmp2?tmp1:tmp2;
    	}
    	if(str[0]=='d'){
    	   int i=9,templ=0,tempr=0;
    	   	 string s="";
    	     while(   templ!=tempr|| (  str[i]!=',' && str[i]!=')'    )      ){
    	   	 if(str[i]=='(') templ++;
    	   	 if(str[i]==')') tempr++;
    	   	 s+=str[i];
    	     i++;
    	    }
    	  return count(s)*2;
    	}
    return 0;
    }
    int main()
    {
       string str;
       char ch='
    ';
       while(ch=='
    '){
            str="";
           while(~scanf("%c",&ch)&&ch!='
    ')
             if(ch!=' ')
              str+=ch;
       int len = str.length();
       cout<<count(str)<<endl;
      }
    return 0;
    }
    

    稍微修改了一下,这样好像美观一点,但是换汤不换药,只是函数更加明确了点。。。

    #include <iostream>
    #include <cstdio>
    #include <memory.h>
    using namespace std;
    string s;//记录当前切割出的子串 
    int cut(string str,int i){ //返回当前已经搜索完了的str的i的下一个位置 
    	s="";
    	int templ=0,tempr=0;
        while( templ!=tempr|| (  str[i]!=',' && str[i]!=')'  )  ){
    	  if(str[i]=='(') templ++;
    	  if(str[i]==')') tempr++;
    	  s+=str[i];
    	  i++;
    	}
    	return i+1;
    }
    int count(string str){
        int len = str.length();
        int  tmp1=0,tmp2=0,temp=0,tmp=0; //tmp1,tmp2比较大小时记录两个数  temp记录返回数的时候的值, tmp记录求和的时候的和 
    	if(str[0]<='9'&&str[0]>='0'){
    	  int i=0;  //记录遍历的起始位置 
    	  temp=str[i++]-'0';
    	  while(i<len&&str[i]<='9'&&str[i]>='0'){
    	   temp=temp*10+str[i]-'0';
    	   i++;
    	   }
    	  return temp;
    	}
    	if(str[0]=='a'){//实现add()函数 
    	   int i=4;
    	   for(int x=1;x<=3&&i<len;x++){//注意需要用Len来控制add()函数是双目还是三目运算符 
    	   	 i=cut(str,i);
    	   tmp+=count(s);
    	   }
    	  return tmp;
    	}
    	if(str[0]=='m'){//实现min()、max()函数 
    	   int i=4;
    	   for(int x=1;x<=2;x++){
    	   	i=cut(str,i);  
    	   x==1?tmp1=count(s):tmp2=count(s);
    	   }
    	  if(str[1]=='i')
    	    return tmp1<tmp2?tmp1:tmp2;//返回最小值 
    	return tmp1>tmp2?tmp1:tmp2;//返回最大值 
    	}
    	if(str[0]=='d'){//doubleMe()函数 
    	   int i=9;
    	   	i=cut(str,i);
    	  return count(s)*2;
    	}
      return 0;
    }
    int main()
    {
       string str="";
       char ch;
       while(~scanf("%c",&ch)&&ch!='
    ')
          if(ch!=' ')
             str+=ch;
       cout<<count(str);
    return 0;
    }
    




  • 相关阅读:
    scala与java的区别
    寒假第四天
    冲刺(第六天)
    冲刺(第五天)
    冲刺(第四天)
    冲刺(第三天)
    冲刺(第二天)
    第十周总结
    冲刺(第一天)
    文本中单词统计
  • 原文地址:https://www.cnblogs.com/zswbky/p/5431986.html
Copyright © 2011-2022 走看看