比如 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;
}