#include "stdafx.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "malloc.h"
#include
using namespace std;
#define N 1000
typedef struct input *Pin;//表达式链结点
struct input
{
int info;//数字用数值存储,符号用对应的ASCII码存储
int type;//标记:0为数字,1为符号
Pin next;
}head;
typedef struct node *pnode;//栈结点
struct node
{
int info; //结点内容
pnode next;
};
struct LinkStack
{
pnode top;
};
typedef struct LinkStack * PLinkStack;
PLinkStack OPTR, OPND;//符号栈、数值栈
Pin E;
Pin now;
char in[N];
int top(PLinkStack plstack);//取栈顶元素
void push(PLinkStack plstack, int n);//入栈
int pop(PLinkStack plstack);//出栈
int signature(int n);//符号处理模块
int transform(int c);//将运算符转换成符号分析表中的坐标
int cmp(int i, int j);//查符号分析表,返回优先级
int less(Pin E);//符号表小于操作
int equal(Pin E);//符号表等于操作
int greater(Pin E);//符号表大于操作
void change();////将输入字符串转化为链表,在输入表达式前后各加一个#
void start();//获得输入字符,检测其合法性
Pin provide();//每次调用时返回一个结点
int main()
{
int flag1 = 1, flag2 = 1, temp, value;
OPND = (struct LinkStack *) malloc(sizeof(struct LinkStack));
OPTR = (struct LinkStack *) malloc(sizeof(struct LinkStack));
while (flag1)//控制可以循环输入表达式
{
flag2 = 1;
OPND->top = NULL;
OPTR->top = NULL;
push(OPTR, '#');
start();//获得输入字符,检测其合法性
printf("后缀表达式:");
while (flag2 != 0)
{
E = provide();//获得一个结点,数字/符号
if (E->type == 0)//数字处理
{
printf("%d ", E->info);//输出后缀式子控制
push(OPND, E->info);
}
else if (E->type == 1)//符号处理
{
temp = signature(E->info);
if (temp == 1)
{
value = pop(OPND);//表达式的值
flag2 = 0;
}
}
else
{
printf("无法获得结点信息!\n");
}
}
printf("\n表达式的值为:%d\n", value);
printf("\n");
}
}
void start()//获得输入字符,检测其合法性
{
head.next = NULL;
now = &head;
int i;
int len;
bool pass = true;
int flag = 0;
while (pass)
{
printf("请输入表达式:");
scanf_s("%s", in);
len = strlen(in);
for (i = 0; i<len; i++)//输入表达式合法检测:只能输入数字、+、-、*、/、(、)。对于")(" "i("v ")i" 格式报错
{
if ((in[i] >= '0'&&in[i] <= '9') || (in[i] == '+') || (in[i] == '-') || (in[i] == '*') || (in[i] == '/') || (in[i] == '(') || (in[i] == ')'))
{
if (!(in[i] >= '0'&&in[i] <= '9') && !(in[i + 1] >= '0'&&in[i + 1] <= '9'))
{
if (!(in[i] == ')' || in[i + 1] == '('))
{
flag = 1;
printf("表达式有误!\n\n");
}
if (in[i] == ')'&&in[i + 1] == '(')
{
flag = 1;
printf("表达式有误!\n\n");
}
}
else if ((in[i] >= '0'&&in[i] <= '9'&&in[i + 1] == '(') || (in[i] == ')'&&in[i + 1] >= '0'&&in[i + 1] <= '9'))
{
flag = 1;
printf("表达式有误!\n\n");
}
}
else
{
flag = 1;
printf("错误:非法字符!\n\n");
}
}
if (flag == 1)
{
flag = 0;
pass = true;
}
else
pass = false;
}
change();
}
void change()//将输入字符串转化为链表,在输入表达式前后各加一个#
{
int num = 0;
char *p, *q;
p = &in[0];
q = &in[1];
while (*p != '\0')
{
if (*p >= '0'&&*p <= '9')
{
num = num * 10 + (*p - '0');
if (!(*q >= '0'&&*q <= '9'))
{
Pin temp = (Pin)malloc(sizeof(struct input));
temp->next = NULL;
now->next = temp;
now = temp;
temp->info = num;
temp->type = 0;
num = 0;
}
}
else
{
Pin temp = (Pin)malloc(sizeof(struct input));
temp->next = NULL;
now->next = temp;
now = temp;
temp->info = *p;
temp->type = 1;
}
p++;
q++;
}
Pin temp = (Pin)malloc(sizeof(struct input));
temp->next = NULL;
temp->info = '#';
temp->type = 1;
now->next = temp;
now = head.next;
}
Pin provide()//每次调用时返回一个结点
{
Pin temp = now;
now = now->next;
return temp;
}
int top(PLinkStack plstack)//取栈顶元素
{
return plstack->top == NULL ? -1 : plstack->top->info;;
}
void push(PLinkStack plstack, int n)//入栈操作
{
pnode tem = (struct node *)malloc(sizeof(struct node));
tem->info = n;
tem->next = NULL;
if (plstack->top == NULL)
{
plstack->top = tem;
return;
}
tem->next = plstack->top;
plstack->top = tem;
return;
}
int pop(PLinkStack plstack)//出栈操作
{
int tem;
if (plstack->top == NULL)
return -1;
tem = plstack->top->info;
plstack->top = plstack->top->next;
return tem;
}
int signature(int n)
{
int i, j, temp;//i前一个符号,j后一个符号
int comp;
if (top(OPTR) == -1) { push(OPTR, n); }//栈为空,直接压入栈
else
{
comp = cmp(top(OPTR), n);//比较运算符优先级
}
switch (comp)
{
case -1:temp = less(E); break;
case 0:temp = equal(E); break;
case 1:temp = greater(E); break;
}
if (n == 35 && top(OPTR) != 35)//!!!当前符号为表达式末尾的#,若符号栈内有未计算的符号,递归调用符号处理
{
temp = signature(n);
}
return temp;
}
int less(Pin E)//当前符号进栈OPTR
{
push(OPTR, E->info);
return 0;
}
int equal(Pin E)
{
int z;
if (E->info == 35) return 1;//当前符号为表达式末尾的#
else
{
z = pop(OPTR);
return 0;
}
}
int greater(Pin E)//基于当前符号的计算
{
int a, b, t, r, flag = 1, Z;
b = pop(OPND);
a = pop(OPND);
t = pop(OPTR);
printf("%c ", t);
switch (t)
{
case 43:r = a + b; break;//'+'
case 45:r = a - b; break;//'-'
case 42:r = a*b; break;//'*'
case 47:r = a / b; break;//'/'
}
if (E->info == ')') //运算结束后将'('出栈
pop(OPTR);
else
{
if (E->info != '#')
push(OPTR, E->info);
}
push(OPND, r);
return E->info == 35 ? 1 : 0;//是#,分析结束,输出结果;不是#,继续取E
}
int cmp(int i, int j)//查表并返回表中优先级,<为-1,=为0,>为1,-2为出错
{
int first, second;
int Table[7][7] = { { 1, 1, -1, -1, -1, 1, 1 }, { 1, 1, -1, -1, -1, 1, 1 }, { 1, 1, 1, 1, -1, 1, 1 }, { 1, 1, 1, 1, -1, 1, 1 }, { -1, -1, -1, -1, -1, 0, -2 }, { 1, 1, 1, 1, -2, 1, 1 }, { -1, -1, -1, -1, -1, -2, 0 } };
return Table[transform(i)][transform(j)];
}
int transform(int ch)//将符号转换为分析表中的坐标
{
int num;
switch (ch)
{
case 43:
num = 0; break;
case 45:
num = 1; break;
case 42:
num = 2; break;
case 47:
num = 3; break;
case 40:
num = 4; break;
case 41:
num = 5; break;
case 35:
num = 6; break;
default:
printf("符号%c错误!", ch);
}
return num;
}
该回答引用ChatGPT
这段代码存在语法错误,导致编译器无法识别 less 函数的定义,因此报错“error C2872: 'less': 不明确的符号”。
为了解决这个问题,我们需要在代码中添加 less 函数的完整定义,或者在代码中包含 头文件,这样就可以使用 STL 中提供的 std::less 函数对象,该函数对象可以用于对各种数据类型进行比较,并返回一个 bool 类型的值表示比较结果。