求字符串表达式的值,这里主要使用的知识是栈.为了更好的使用,这里定义一个栈头文件,其中包括基本的栈操作.
#ifndef STACK_H
#define STACK_H
typedef char datatype;
typedef struct
{
datatype *arr;
int top;
int size;
}stack;
void init_stack(stack *s, int n = 100)/*栈的初始化*/
{
s->size = n;
if (!(s->arr = (datatype*)malloc(n * sizeof(datatype))))
{
printf("Malloc error!\n");
}
s->top = 0;
}
void destroy_stack(stack *s)/*栈的销毁*/
{
delete s->arr;
s->arr = NULL;
}
void push_stack(stack *s, datatype val)/*入栈操作*/
{
if (s->top >= s->size)
{
printf("The stack is full!\n");
}
else
{
s->arr[s->top++] = val;
}
}
int is_empty(stack *s)/*查看栈是否为空*/
{
return (s->top == 0) ? 1 : 0;
}
datatype pop_stack(stack *s)/*出栈操作*/
{
if (s->top == 0)
{
return 0;
printf("The stack is empty!");
}
else
{
return s->arr[--(s->top)];
}
}
datatype get_top(stack *s)/*取得栈顶元素*/
{
if (s->top == 0)
{
return 0;
printf("The stack is empty!");
}
else
{
return s->arr[s->top-1];
}
}
#endif
求表达式的值,首先将表达式转换成后缀表达式, 然后再求后缀表达式的值.(这里字符串表达式的格式未能完全检测是否正确)
/*
Author: Mcdragon
Date: 26-10-11 09:23
Description: 计算字符串表达式的值(支持括号与小数).
*/
#include <stdio.h>
#include <malloc.h>
#include "stack.h"
#define STR_LEN 100
int braket_match(char *str, stack *s); /*检测一个表达式的括号是否匹配:*/
double calulate(char *str); /*求出后缀表达式的值*/
void change_expr(char *input, char *out, int len); /*将中缀表达式转换成后缀表达式*/
int is_operator(char ch); /*判断是否是运算符*/
int is_digit(char ch); /*判断是否是数字*/
int priority(char ch); /*返回运算符的优先级*/
int main()
{
stack s;
char str[STR_LEN], post_str[STR_LEN];
init_stack(&s,STR_LEN);
printf("Please input an express!\n");
scanf("%s",str);
printf("---------------------------------\n\n");
if(!braket_match(str,&s))
{
printf("Express Error!\n");
return 0;
}
else
{
printf("%s",str);
}
change_expr(str, post_str, STR_LEN);
//printf("%s\n",post_str);
printf(" = %.3f\n", calulate(post_str));
destroy_stack(&s);
getchar();getchar();
return 0;
}
double calulate(char *str)
{
double doub_stack[STR_LEN];
int doub_stack_top = 0;
int i = 0;
double tmp = 0;
int count;
int point_position = 0;
while(str[i] != '\0')
{
if(is_digit(str[i]))
{
count = 0;
point_position = 0;
tmp = str[i] - '0';
while(str[++i] != ' ')
{
count++;
if(str[i] == '.')
{
point_position = count;
}
else
{
tmp *= 10;
tmp += str[i] - '0';
}
}
if (point_position)
{
while(count > point_position)
{
tmp /= 10;
count--;
}
}
doub_stack[doub_stack_top++] = tmp;
}
if(is_operator(str[i]))
{
switch(str[i])
{
case '+':
doub_stack[doub_stack_top - 2] = doub_stack[doub_stack_top - 2]
+ doub_stack[doub_stack_top - 1];
doub_stack_top--;
break;
case '-':
doub_stack[doub_stack_top - 2] = doub_stack[doub_stack_top - 2]
- doub_stack[doub_stack_top - 1];
doub_stack_top--;
break;
case '*':
doub_stack[doub_stack_top - 2] = doub_stack[doub_stack_top - 2]
* doub_stack[doub_stack_top - 1];
doub_stack_top--;
break;
case '/':
doub_stack[doub_stack_top - 2] = doub_stack[doub_stack_top - 2]
/ doub_stack[doub_stack_top - 1];
doub_stack_top--;
break;
default:
break;
}
}
i++;
}
return doub_stack[0];
}
int braket_match(char *str, stack *s)
{
int i = 0;
while(str[i] != '\0')
{
if(str[i] == '(' || str[i] == '[' || str[i] == '{')
{
push_stack(s,(int)str[i]);
}
if(str[i] == ')' || str[i] == ']' || str[i] == '}')
{
switch(str[i])
{
case ')':
if (pop_stack(s) != '(')
{
return 0;
}
break;
case ']':
if (pop_stack(s) != '[')
{
return 0;
}
break;
case '}':
if (pop_stack(s) != '{')
{
return 0;
}
break;
default:
break;
}
}
i++;
}
return (is_empty(s)) ? 1 : 0;
}
/*将中缀表达式表示成后缀表达式*/
void change_expr(char *input, char *out, int len)
{
stack num_stack, op_stack;
int i = 0;
int j = 0;
init_stack(&num_stack, len);
init_stack(&op_stack, len);
while(input[i] != '\0')
{
if(input[i] == '(')
{
push_stack(&op_stack, input[i]);
}
else if(input[i] == ')')
{
if(is_empty(&op_stack))
{
printf("Operator error!\n");
return;
}
while(get_top(&op_stack) != '(')
{
out[j++] = pop_stack(&op_stack);
out[j++] = ' ';
}
pop_stack(&op_stack);
}
else if(is_operator(input[i]))
{
if(is_empty(&op_stack) || priority(input[i]) > priority(get_top(&op_stack)))
{
push_stack(&op_stack, input[i]);
}
else
{
while(!(is_empty(&op_stack)) && priority(input[i]) <= priority(get_top(&op_stack)))
{
out[j++] = pop_stack(&op_stack);
out[j++] = ' ';
}
if(is_empty(&op_stack) || priority(input[i]) > priority(get_top(&op_stack)))
{
push_stack(&op_stack, input[i]);
}
}
}
else
{
while(is_digit(input[i]))
{
out[j++] = input[i++];
}
out[j++] = ' ';
i--;
}
i++;
}
while(!(is_empty(&op_stack)))
{
out[j++] = pop_stack(&op_stack);
}
out[j] = '\0';
destroy_stack(&num_stack);
destroy_stack(&op_stack);
}
int is_operator(char ch)
{
return (ch == '+' || ch == '-' || ch == '*' || ch == '/') ? 1 : 0;
}
int is_digit(char ch)
{
return (ch >= '0' && ch <= '9' || ch == '.') ? 1 : 0;
}
int priority(char ch)
{
switch(ch)
{
case '+':
case '-':
return 1; break;
case '*':
case '/':
return 2; break;
default:
return 0; break;
}
}
最后输出结果: