计算字符串的程序优化

比如 char *pString  = "332*222*22-233-23+33/32/32*233+323-23323";

里面只有数字和+ - * / 四个运算符

算法核心思想:

     取出三个操作数和三个运算符,如果第一个运算符大于或则等于第二个

则处理第一操作数和第二操作数,否则的话是处理第二操作数和第三操作数 

一直执行到程序结束

我看到有些人用两个栈来实现

我觉得这样程序浪费存储空间而且程序执行效率也不高

因为栈是要存储空间的,如果你用STL的Stack

你要知道它是用 Deque来实现的

而且在入栈和出栈的时候都需要函数调用的 


/**************************************************
* 文 件 名:  Compute_string.cpp
* 文件描述:  计算一个字符串的实现文件
* 创 建 人:  刘基伟
* 创建日期:  2007年 5月 19日
* 版 本 号:  1.0
* 修改纪录:  暂无
*************************************************/


                /**************************************************
              *                                                 *
              *                   加载头文件                    *
             *                                                 *
              **************************************************/
#include <iostream>

using namespace std;

                /**************************************************
              *                                                 *
              *                   预处理命令                    *
             *                                                 *
              **************************************************/

#define     LOW         0
#define     HIGH        1
#define     MULTIPLY    42
#define     PLUS        43
#define     SUBTRACT    45
#define     DIVIDE      47

/*=========================================================
* 函 数 名: Compute_priority(const char, int &)

* 参数说明: chOperator              操作符
             irefOperator_opt_flag   操作符的优先级

* 功能描述:  计算chFirst_opt的优先级

* 返 回 值:  void
==========================================================*/

void Compute_priority(const char chOperator, int &irefOperator_opt_flag)
{
 if((chOperator == '+') || (chOperator == '-'))   // 重新计算第一操作符的优先级
 {
  irefOperator_opt_flag = LOW;
 }
 else
 {
  irefOperator_opt_flag = HIGH;
 }
}

/*=========================================================
* 函 数 名: Compute(const char, float&, float&)

* 参数说明: chOperator            第一操作符
    frefFirst_value       第一操作数的引用
    rrefSecond_value      第二操作数的引用

* 功能描述:  处理frefFirst_value和frefSecond_value

* 返 回 值:  void
==========================================================*/

void Compute_tow_value(const char chOperator, float &frefFirst_value, float &frefSecond_value)
{
 switch((int)chOperator)               // 计算第一操作数
 {
 case MULTIPLY:
  frefFirst_value *= frefSecond_value;
  break;
 case PLUS:
  frefFirst_value += frefSecond_value;
  break;
 case SUBTRACT:
  frefFirst_value -= frefSecond_value;
  break;
 case DIVIDE:
  frefFirst_value /= frefSecond_value;
  break;
 default:
  break;
 }
}

/*==========================================================
* 函 数 名: Compute_first_second(const int&, const int&,
        const char, const char ,
        float &, float &, int &)

* 参数说明: irefFirst_opt_flag    第一操作符优先级的引用
             irefSecond_opt_flag   第二操作符优先级的引用
    chFirst_opt           第一操作符
    chSecond_opt          第二操作符
    frefFirst_value       第一操作数的引用
    frefSecond_value      第二操作数的引用
    frefThird_value       第三操作数的引用

* 功能描述:按照优先级处理frefFirst_value,
            frefSecond_value,frefThird_value

* 返 回 值:  void
==========================================================*/

void Compute_first_second(const int &irefFirst_opt_flag, const int &irefSecond_opt_flag,
        const char chFirst_opt, const char chSecond_opt,
        float &frefFirst_value, float &frefSecond_value, float &frefThird_value)
{
 if(irefFirst_opt_flag >= irefSecond_opt_flag)  //第一操作符的优先级大于等于第二操作符
 {
  Compute_tow_value(chFirst_opt, frefFirst_value, frefSecond_value);
  Compute_tow_value(chFirst_opt,frefFirst_value, frefThird_value);
 }
 else                   //第一操作符的优先级小于第二操作符           
 {
  Compute_tow_value(chSecond_opt, frefSecond_value, frefThird_value);
     Compute_tow_value(chFirst_opt, frefFirst_value, frefSecond_value);
 } 
}

/*==========================================================
* 函 数 名: Initialize_first(char *const, float &,
       char *,char *&,
       char &, int &,const char *)

* 参数说明:  pString              为传入的数组
              frefFirst_value      第一操作数的引用
     pFirst_value         第一操作数的开始地址
     pFirst_opt           第一操作符的地址
     chrefFirst_opt       第一操作符的引用
     irefFirst_opt_flag   第一操作符优先级引用
     pEnd                 字符串的结束地址

* 功能描述:  计算第一操作数和第一操作符及其优先级

* 返 回 值:  void
==========================================================*/

void Initialize_first(char *const pString, float &frefFirst_value,
         char *pFirst_value,char *&pFirst_opt,
          char &chrefFirst_opt, int &irefFirst_opt_flag,const char *pEnd)
{  
 frefFirst_value = atoi(pFirst_opt);            // 计算第一个操作数
 while((*pFirst_value >= '0') && (*pFirst_value <= '9') && (pFirst_value != pEnd))
 {
  pFirst_value++;
 }
 pFirst_opt  = pFirst_value;                             // 找到第一操作符的位置
 chrefFirst_opt = *pFirst_opt;                           // 计算第一个操作符
    Compute_priority(chrefFirst_opt, irefFirst_opt_flag);   // 计算第一操作符的优先级
}

/*==========================================================
* 函 数 名: Initialize_second(char *const, char *,
        char *,  char *&, float &,
        char &, int &, char *)

* 参数说明:  pString              为传入的数组
              pSecond_value        第二操作数的开始地址
     pFirst_opt           第一操作符的地址
     pSecond_opt          第二操作符的地址
     frefSecond_value     第二操作数的引用
     chrefSecond_opt      第二操作符
     irefSecond_opt_flag  第二操作符优先级别的引用
     pEnd                 字符串的结束地址

* 功能描述:  计算第二操作数和第二操作符及其优先级

* 返 回 值:  void
==========================================================*/

void Initialize_second(char *const pString, char *pSecond_value,
        char *pFirst_opt,  char *&pSecond_opt, float &frefSecond_value,
        char &chrefSecond_opt, int &irefSecond_opt_flag, char *pEnd)
{
 pSecond_value    = pFirst_opt + 1;      
 frefSecond_value = atoi(pSecond_value);        // 计算第二个操作数
    while((*pSecond_value >= '0') && (*pSecond_value <= '9') && (pSecond_value != pEnd))
    {
  pSecond_value++;
 }
 pSecond_opt  = pSecond_value;                              // 找到第二个操作符的位置
    chrefSecond_opt = *pSecond_opt;                            // 计算第二个操作符
 Compute_priority(chrefSecond_opt, irefSecond_opt_flag);    // 计算第二操作符的优先级
}

/*=========================================================
* 函 数 名: Initialize_third(char *const, char *,
       char *,char *&,
       float &, char &, char *)

* 参数说明:  pString              为传入的数组
              pThird_value         第三操作数的开始地址
     pSecond_opt          第二操作符的地址
     pThird_opt           第三操作符的地址
     irefThird_value      第三操作数
     chrefThird_opt       第三操作符的引用
     pEnd                 字符串的结束地址

* 功能描述:  计算第三操作数和第三操作符及其优先级

* 返 回 值:  void
==========================================================*/

void Initialize_third(char *const pString, char *pThird_value,
       char *pSecond_opt,char *&pThird_opt,
       float &irefThird_value, char &chrefThird_opt, char *pEnd)
{
 pThird_value    = pSecond_opt + 1;            
 irefThird_value = atoi(pThird_value);          // 计算第三个操作数
    while((*pThird_value >= '0') && (*pThird_value <= '9') && (pThird_value != pEnd))
    {
  pThird_value++;
 }
 pThird_opt     = pThird_value;                 // 找到第三个操作符的位置
 chrefThird_opt = *pThird_opt;                  // 计算第三个操作符
}

/*=======================================================
* 函 数 名: String_to_float(char *const, int )
* 参数说明:  pString 为传入的数组
              iCount 为数组的个数
* 功能描述:  当一个字符串的符号大于等于三个时
              计算一个字符串里面的值
              字符串里面仅含有数值和 +*-/ 四个符号
* 返 回 值:  float
=======================================================*/

float String_to_float(char *const pString, int iCount)
{
 /**************************************************
 *                                                 *
 *                   变量声明                      *
 *                                                 *
 **************************************************/

 float fFirst_value;       // 第一操作数
 float fSecond_value;      // 第二操作数
 float fThird_value;       // 第三操作数
 int   iFirst_opt_flag;    // 第一操作符的优先级
 int   iSecond_opt_flag;   // 第二操作符的优先级
 char  chFirst_opt;        // 第一操作符
 char  chSecond_opt;       // 第二操作符
 char  chThird_opt;        // 第三操作符
 char  *pCurrent;          // 字符串当前指针
 char  *pBegin;            // 字符串的开始位置
 char  *pEnd;              // 字符串的结束位置
 char  *pFirst_opt;        // 第一操作数开始位置
 char  *pSecond_opt;       // 第二操作数开始位置
 char  *pThird_opt;        // 第三操作数开始位置
 char  *pFirst_value;      // 第一操作符开始位置
 char  *pSecond_value;     // 第二操作符开始位置
 char  *pThird_value;      // 第三操作符开始位置
 
    /**************************************************
 *                                                 *
 *                   变量初始化                    *
 *                                                 *
 **************************************************/
 
 pCurrent      = pString;
 pBegin        = pString - 1;
 pEnd          = pString + iCount - 1;
 pFirst_opt    = pString;
 pSecond_opt   = pString;
 pThird_opt    = pString;
 pFirst_value  = pString;
 pSecond_value = pString;
 pThird_value  = pString;
   
 /**************************************************
 *                                                 *
 *          计算第一操作数和第一操作符及其优先级   *
 *                                                 *
 **************************************************/
   
 Initialize_first(pString, fFirst_value, pFirst_value,
                pFirst_opt, chFirst_opt, iFirst_opt_flag, pEnd);

    /**************************************************
 *                                                 *
 *        计算第二操作数和第二操作符及其优先级     *
 *                                                 *
 **************************************************/

    Initialize_second(pString, pSecond_value, pFirst_opt, pSecond_opt,
                  fSecond_value, chSecond_opt, iSecond_opt_flag, pEnd);

 /**************************************************
 *                                                 *
 *               计算第三操作数和第三操作符        *
 *                                                 *
 **************************************************/
 Initialize_third(pString, pThird_value, pSecond_opt, pThird_opt,
                 fThird_value, chThird_opt, pEnd);
   
 /**************************************************
 *                                                 *
 *           进入循环体,一直处理到最后            *
 *                                                 *
 **************************************************/

 while( true )
 {
  /**************************************************
     *                                                 *
     *  比较第一操作符和第二操作符, 再分别进行处理    *
     *                                                 *
     **************************************************/

  if(iFirst_opt_flag >= iSecond_opt_flag)      // 第一操作符的优先级大于等于第二操作符
  {
   Compute_tow_value(chFirst_opt, fFirst_value, fSecond_value);  // 处理第一操作数和第二操作数

   /**************************************************
   *                                                 *
   *                   变量重置                      *
   *                                                 *
   **************************************************/

   fSecond_value = fThird_value;           // 重新设定第二操作数
   pFirst_opt    = pSecond_opt;            // 重新设定第一操作符的位置
   pSecond_opt   = pThird_opt;             // 重新设定第二操作符的位置
   chFirst_opt   = *pFirst_opt;            // 重新设定第一操作符
   chSecond_opt  = *pSecond_opt;           // 重新设定第二操作符
  
   Compute_priority(chFirst_opt, iFirst_opt_flag);     // 计算第一操作符的优先级
   Compute_priority(chSecond_opt, iSecond_opt_flag);   // 计算第一操作符的优先级
  }
  else                     //第一操作符的优先级小于第二操作符
  {
   Compute_tow_value(chSecond_opt, fSecond_value, fThird_value);   // 处理第二操作数和第三操作数
   /**************************************************
   *                                                 *
   *                   变量重置                      *
   *                                                 *
   **************************************************/
   pSecond_opt  = pThird_opt;                          // 重新设定第二操作符
   chSecond_opt = *pSecond_opt;
   Compute_priority(chFirst_opt, iFirst_opt_flag);     // 计算第一操作符的优先级
   Compute_priority(chSecond_opt, iSecond_opt_flag);   // 计算第一操作符的优先级
  }
       /**************************************************
         *                                                 *
          *      计算第三操作数和第三操作符                 *
         *                                                 *
         **************************************************/

  pThird_value = pThird_opt + 1;            
  fThird_value = atoi(pThird_value);      // 计算第三个操作数
  while((*pThird_value >= '0') && (*pThird_value <= '9') )
  {
   pThird_value++;
  }
  if(pThird_value == pEnd)              
  {
   /**************************************************
         *                                                 *
          *      到了末尾,处理函数然后退出                 *
         *                                                 *
          *    对剩下的三个操作数进行处理,然后结束本函数   *  
         *                                                 *
         **************************************************/

   Compute_first_second(iFirst_opt_flag, iSecond_opt_flag,
    chFirst_opt, chSecond_opt,
    fFirst_value, fSecond_value, fThird_value);
   return fFirst_value;
  }
  else                      
  {
   /**************************************************
         *                                                 *
          *     没有结束,计算第三操作符,                   *  
         *                                                 *
         **************************************************/

   pThird_opt  = pThird_value;     // 找到第三个操作符的位置
   chThird_opt = *pThird_opt;      // 计算第三个操作符
  }
 }
}

/*=======================================================
* 函 数 名: Compute_string(char *const, int )
* 参数说明:  pString 为传入的数组
              iCount 为数组的个数
* 功能描述:  计算一个字符串里面的值
              字符串里面仅含有数值和 +*-/ 四个符号
* 返 回 值:  float
=======================================================*/

float Compute_string(char *const pString,int iCount)
{
 /**************************************************
 *                                                 *
 *             如果字符串为空就退出程序            *
 *                                                 *
 **************************************************/
 if(strlen(pString) == 0)
  exit(0);
 /**************************************************
 *                                                 *
 *                   变量声明                      *
 *                                                 *
 **************************************************/

 float fFirst_value;       // 第一操作数
 float fSecond_value;      // 第二操作数
 float fThird_value;       // 第三操作数
 int   iFirst_opt_flag;    // 第一操作符的优先级
 int   iSecond_opt_flag;   // 第二操作符的优先级
 char  chFirst_opt;        // 第一操作符
 char  chSecond_opt;       // 第二操作符
 char  *pFirst_opt;        // 第一操作数开始位置
 char  *pSecond_opt;       // 第二操作数开始位置
 char  *pThird_opt;        // 第三操作数开始位置
 char  *pFirst_value;      // 第一操作符开始位置
 char  *pSecond_value;     // 第二操作符开始位置
 char  *pThird_value;      // 第三操作符开始位置
 char  *pCurrent;          // 字符串的当前的位置
    char  *pEnd;              // 字符串的结束的位置
 int   iOperator_count;    // 计算操作符号的个数
    float fReturn_value;     // 函数的返回值

 /**************************************************
 *                                                 *
 *                   变量初始化                    *
 *                                                 *
 **************************************************/

 pFirst_opt      = pString;
 pSecond_opt     = pString;
 pThird_opt      = pString;
 pFirst_value    = pString;
 pSecond_value   = pString;
 pThird_value    = pString;
 pCurrent        = pString;
 pEnd            = pCurrent + iCount - 1;
 iOperator_count = 0;
 fReturn_value   = 0.0;

 /**************************************************
 *                                                 *
 *                   寻找有几个操作符              *
 *                                                 *
 **************************************************/

 while(pCurrent != pEnd)
  {
   if((*pCurrent < '0') || (*pCurrent > '9'))
   {
    iOperator_count++;
   }
   pCurrent++;
  }

    /**************************************************
 *                                                 *
 *            根据操作符个数,分别处理             *
 *                                                 *
 **************************************************/

    switch(iOperator_count)
 {
 case 0:              // 没有操作符
  fReturn_value = atoi(pString);
  break;
 case 1:                                // 一个操作符
  fFirst_value = atoi(pFirst_opt);            // 计算第一个操作数
  while((*pFirst_value >= '0') && (*pFirst_value <= '9') && (pFirst_value != pEnd))
  {
   pFirst_value++;
  }
  pFirst_opt  = pFirst_value;                 // 找到第一操作符的位置
  chFirst_opt = *pFirst_opt;                  // 计算第一个操作符
  Compute_priority(chFirst_opt, iFirst_opt_flag);   // 计算第一操作符的优先级
  pSecond_value = pFirst_opt + 1;      
  fSecond_value = atoi(pSecond_value);          // 计算第二个操作数
  Compute_tow_value(chFirst_opt, fFirst_value, fSecond_value);
        fReturn_value = fFirst_value;
  break;
 case 2:                               // 两个操作符

  char chThird_opt;
   /**************************************************
         *                                                 *
         *          计算第一操作数和第一操作符及其优先级   *
         *                                                 *
         **************************************************/
   
 Initialize_first(pString, fFirst_value, pFirst_value,
                pFirst_opt, chFirst_opt, iFirst_opt_flag, pEnd);

            /**************************************************
         *                                                 *
         *        计算第二操作数和第二操作符及其优先级     *
          *                                                 *
           **************************************************/

    Initialize_second(pString, pSecond_value, pFirst_opt, pSecond_opt,
                  fSecond_value, chSecond_opt, iSecond_opt_flag, pEnd);

         /**************************************************
         *                                                 *
         *               计算第三操作数和第三操作符        *
         *                                                 *
         **************************************************/
 
 Initialize_third(pString, pThird_value, pSecond_opt, pThird_opt,
  fThird_value, chThird_opt, pEnd);
           
         /**************************************************
         *                                                 *
          *            对三个操作数进行处理,               *
   *                                                 *
   *             然后把结果赋给fReturn_value         *  
         *                                                 *
         **************************************************/
 
 Compute_first_second(iFirst_opt_flag, iSecond_opt_flag,
  chFirst_opt, chSecond_opt,
  fFirst_value, fSecond_value, fThird_value);
 fReturn_value = fFirst_value;
  break;
 case 3:               // 三个或者三个以上操作符
 default:
  fReturn_value = String_to_float(pString,iCount);  // 交给 String_to_float 函数处理
        break;
 }
 return fReturn_value;
}

int main()
{
    char pString[] = "21*4*33*2+42-21-23-14*3*543/71+242+22*43";
 float j = 21*4*33*2+42-21-23-14*3*543/71+242+22*43;
 float i = Compute_string(pString, sizeof(pString));
 cout<<i<<endl;
 cout<<j<<endl;
 return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值