版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
#include <iostream>
#include <Windows.h>
#include <string>
#include <sstream>
/***************内存检测区*********************/
#define _CRTDBG_MAP_ALLOC //* 这个是 相当于一种开关 打开这个内存检测的开关
#include <cstdlib> //*
#include <crtdbg.h> //*
#ifdef _DEBUG //*
#ifndef DBG_NEW //*
#define DBG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__)//*
#define new DBG_NEW //*
#endif //*
#endif
/***************宏定义和类型转换区*****************/
#define MAX_SIZE 128
#define STACK_S typedef
#define ELEM_TYPE int
using namespace std;
/***************结构体区*********************/
STACK_S struct stack_s {
ELEM_TYPE* base; // 栈底标记
ELEM_TYPE* top; // 栈顶元素
}stack;
static int DeBug = 1;
/***************函数定义区*********************/
bool isEmpty(stack& st);
bool isFull(stack& st);
// 1.初始化栈
bool initStack(stack& st);
// 2.入栈 e是要入栈的元素
bool pushStack(stack& st, ELEM_TYPE e);
// 3.出栈 e是要出栈的元素
bool popStack(stack& st, ELEM_TYPE& e);
// 4.销毁栈
void destroyStack(stack& st);
// 5.栈的遍历
void printStack(stack& st);
// 6.栈的长度
int stackLen(stack& st);
// 7.得到栈顶的指针
ELEM_TYPE* getTop(stack& st);
/***************有关运算式子的函数声明区*******************/
// 判断是否为 运算符
bool isOpt(int a, char *optstr, int lenth);
// 运算符优先级的比较 左大于右 就返回 > 等于的话 就放回 = 否则返回 <
char priority(char lopt, char ropt);
// 计算函数
void oper(ELEM_TYPE outvalue_1, char outopt, ELEM_TYPE outvalue_2, ELEM_TYPE& result);
/***************用户接口区*********************/
int main(void) {
const char* str = " 16*16*(1+1)+8 =";
char optstr[] = { '+', '-', '*', '/', '(', ')', '#', '='};
stack opt; // 这个是符号栈
stack value; // 这个式值栈
initStack(opt);
initStack(value);
pushStack(opt, (int)('#')); //做一个开始的标记 与第一个进来的相互比较
ELEM_TYPE result = 0; //结果 //以为value 内部也是 char 类型
char buf[128];
int len = 0;
char* start = nullptr;
char* end = nullptr;
char intbuf[16];
cout << "***********************************************" << endl; //
while ((char)(*getTop(opt)) != '#' || str[len] != '=') {
if (isspace(str[len])) {
if (DeBug)printf_s("第 %d 个为空!\n", len + 1);
len++;
continue;
}
ELEM_TYPE ret = (ELEM_TYPE)str[len]; //保存当前读取的 字符
ELEM_TYPE outvalue_1, outvalue_2; //用来保存出栈的值
ELEM_TYPE outopt;
if (!isOpt(ret, optstr, sizeof(optstr) / sizeof(optstr[0]))) { //不是运算符的话就是 数值
{// 这个模块是把 连续的 数字字符 转换成 int
start = (char*)str + len;
end = start + 1;
while (!isOpt(int(*end), optstr, sizeof(optstr) / sizeof(optstr[0]))) {
end++;
}
snprintf(intbuf, sizeof(intbuf), start, end - start);
ret = atoi(intbuf);
}
if (DeBug)printf_s("第 %d 个为数字: %d!\n", len + 1, ret); //入栈之后就继续扫描
pushStack(value, ret);
len += end-start;
continue;
}else {
if (DeBug)printf_s("第 %d 个为运算符,正在进行操作 %c !\n", len + 1, (char)ret);
switch (priority((char)(*getTop(opt)), (char)ret))
{
case '<':
pushStack(opt, ret);
if (DeBug)printf_s("第 %d 个为运算符,入栈 %c !\n", len + 1, ret);
len++;
break;
case '>':
popStack(opt, outopt);
popStack(value, outvalue_1);
popStack(value, outvalue_2);
oper(outvalue_2, (char)outopt, outvalue_1, result); //开始运算
pushStack(value, result);
if (DeBug)printf_s("**********结果 %d 入栈 %c 出栈!\n", result, outopt);
break;
case '=':
popStack(opt, outopt);
if (DeBug)printf_s(" ‘=’的情况下 %c 出栈!\n", outopt);
len++;
break;
}
}
}
const char* laopo = "珂珂宝贝1314";
cout << "开始输出结果!" << endl;
sprintf_s(buf, "%s %d ", str, *getTop(value));
cout << buf << endl;
Sleep(4000);
cout << "等等, 答案好像不对 !" << endl;
Sleep(4000);
sprintf_s(buf, "%s %d%s ", str, *getTop(value), laopo);
cout << "应该是 :";
cout << buf << endl;
destroyStack(opt);
destroyStack(value);
system("pause");
_CrtDumpMemoryLeaks();
return 0;
}
/***************函数定义区*********************/
bool initStack(stack& st) {
st.base = new ELEM_TYPE[MAX_SIZE];
if (!st.base) {
return false;
}
st.top = st.base;
return true;
}
bool pushStack(stack& st, ELEM_TYPE e) {
if ((st.top - st.base) == MAX_SIZE) {//栈已经满了
return false;
}
*(st.top++) = e;
return true;
}
bool popStack(stack& st, ELEM_TYPE& e) {
if (st.base == st.top) {//栈为空
return false;
}
e = *(--st.top);
return true;
}
void destroyStack(stack& st) {
st.top = nullptr;
if (st.base) delete[] st.base;
return;
}
inline bool isEmpty(stack& st) {
if (st.base == st.top) {
return true;
}
else {
return false;
}
}
inline bool isFull(stack& st) {
if (st.top - st.base == MAX_SIZE) {
return true;
}
else {
return false;
}
}
void printStack(stack& st) {
auto tmp = st.base;
int i = 1;
while (tmp != st.top) {
printf_s(" %c \n", *tmp);
tmp++;
}
return;
}
inline int stackLen(stack& st) {
auto len = st.top - st.base;
return len;
}
inline ELEM_TYPE* getTop(stack& st) {
if (!isEmpty(st)) {
return st.top - 1;
}
else
return nullptr;
}
bool isOpt(int a, char* optstr, int lenth) {
for (int i = 0; i < lenth; i++) {
if ((char)a == optstr[i])
return true;
}
return false;
}
char priority(char lopt, char ropt) {
switch (lopt)
{
case '+':
switch (ropt)
{
case '=':
case '+':
case '-':
case ')':
case '#':
return '>';
default:
return '<';
}
case '-':
switch (ropt)
{
case '=':
case '+':
case '-':
case ')':
case '#':
return '>';
default:
return '<';
}
case '*':
switch (ropt)
{
case '(':
return '<';
default:
return '>';
}
case '/':
switch (ropt)
{
case '(':
return '<';
default:
return '>';
}
case '(':
switch (ropt)
{
case ')':
return '=';
default:
return '<';
}
case '#':
switch (ropt)
{
case '#':
case '=':
return '=';
default:
return '<';
}
}
return '\0';
}
void oper(ELEM_TYPE outvalue_1, char outopt, ELEM_TYPE outvalue_2, ELEM_TYPE& result) {
int result_1 = 0;
int value_1 = outvalue_1;
int value_2 = outvalue_2;
switch (outopt) {
case '+':
result_1 = value_1 + value_2;
break;
case '-':
result_1 = value_1 - value_2;
break;
case '*':
result_1 = value_1 * value_2;
break;
case '/':
result_1 = value_1 / value_2;
break;
default:
break;
}
result = result_1 ;
return;
}