- 支持 + - * / ( ) 运算符
- 支持小数运算
- 可以识别正负号(如-1,+3,..)
- 可以识别 "(" 前或 ")" 后省略的 * 号
- 可以检测错误(1,双目出错 2,单目出错 3,括号不匹配 4,其它字符 5,小数点出错)
#include<stdio.h>
#include<math.h>
#define MAXSIZE 100
#define NUMBER 1
#define SYMBOL 0
#define EXIST 1
#define UNEXIST 0
//数字栈
typedef struct numberNode{
double data;
struct numberNode *next;
}stackNode_number;
//符号栈
typedef struct symbolNode{
char data;
struct symbolNode *next;
}stackNode_symbol;
//字符串
char buf[MAXSIZE];
//数字栈运算
stackNode_number *initStackList_number();
int stackEmpty_number(stackNode_number *head);
int pushStack_number(stackNode_number *head, double d);
int popStack_number(stackNode_number *head, double *d);
int topStack_number(stackNode_number *head, double *d);
//符号栈运算
stackNode_symbol *initStackList_symbol();
int stackEmpty_symbol(stackNode_symbol *head);
int pushStack_symbol(stackNode_symbol *head, char d);
int popStack_symbol(stackNode_symbol *head, char *d);
int topStack_symbol(stackNode_symbol *head, char *d);
//字符串处理函数
int dealStr(char *h);
//优先级判断
int isPriority(stackNode_symbol *head, char p);
//运算符运算
void dealSymbol(stackNode_symbol *A, stackNode_number *B, char p);
//出栈运算
void fun(stackNode_symbol *A, stackNode_number *B);
int main(){
char *str;
str = fgets(buf,MAXSIZE,stdin);
// printf("%s\n", str);
while(!dealStr(str)){
printf("error!\n");
str = fgets(buf,MAXSIZE,stdin);
}
return 0;
}
int dealStr(char *h)
{
int leftType = SYMBOL;//0数字,1符号
int i=0;
double t=1;//数字系数
char *p = h;
double num = 0;
double n = 0;
double pointStatuse = UNEXIST;
int pointAt;
stackNode_number *stackN = initStackList_number();
stackNode_symbol *stackS = initStackList_symbol();
int tap = 0;
while(p[i] != '\n'){
switch (p[i]) {
case '0':case '1':case '2':
case '3':case '4':case '5':
case '6':case '7':case '8':
case '9':
n = p[i] - '0';
num = num * 10 + n;
leftType = NUMBER;
//当后一个字符不为数字或"."时,将数字压入栈
if(((p[i+1] < 48) || (p[i+1] > 57)) && p[i+1] != '.'){
if(pointStatuse == EXIST){
t *= pow(10,-(i - pointAt));
pointStatuse = UNEXIST;
}
num *= t;
pushStack_number(stackN,num);
num = 0;
t = 1;
}
break;
case '.':
if((p[i+1] < '0' || p[i+1] > '9') && leftType == SYMBOL){
printf("5,");
return 0;
}
if((p[i+1] < '0' || p[i+1] > '9') && leftType == NUMBER){
pointStatuse = UNEXIST;
break;
}
pointStatuse = EXIST;
pointAt = i;
break;
case '+':case '-':
//单目
if(leftType == SYMBOL){
if((p[i+1] < '0' || p[i+1] > '9') && p[i+1] != '.' ){
printf("2,");
return 0;
}
if (p[i] == '-'){
t = -1;
}else{
t = 1;
}
}
//双目
else{
// if(p[i+1] < '0' || p[i+1] > '9')
// return 0;
leftType = SYMBOL;
dealSymbol(stackS, stackN, p[i]);
}
break;
case '*':case '/':
if((p[i+1] < '0' || p[i+1] > '9') && (p[i+1] != '(' && p[i+1] != '.')){
printf("1,");
return 0;
}
leftType = SYMBOL;
dealSymbol(stackS, stackN, p[i]);
break;
case '(':
tap++;
if(leftType == NUMBER){
dealSymbol(stackS, stackN, '*');
}
leftType = SYMBOL;
dealSymbol(stackS, stackN, p[i]);
break;
case ')':
tap--;
dealSymbol(stackS, stackN, p[i]);
if ((p[i+1] >= '0' && p[i+1] <= '9') || p[i+1] == '.') {
dealSymbol(stackS, stackN, '*');
}
break;
default:
printf("4,");
return 0;
}
i++;
}
if(tap){
printf("3,");
return 0;
}
while (!stackEmpty_symbol(stackS)) {
fun(stackS,stackN);
}
double k;
popStack_number(stackN, &k);
printf("k=%.3lf\n", k);
return 1;
}
//处理符号
void dealSymbol(stackNode_symbol *A, stackNode_number *B, char p){
char a;
//符号栈为空时直接入栈
if (stackEmpty_symbol(A)){
if(p == '(' && !stackEmpty_number(B)){
pushStack_symbol(A,'*');
}
pushStack_symbol(A,p);
}else{
switch (p) {
case '(':
pushStack_symbol(A,p);
break;
case ')':
topStack_symbol(A,&a);
if (a == '(') {
popStack_symbol(A,&a);
}
while (a != '(') {
fun(A,B);
topStack_symbol(A,&a);
if(a == '('){
popStack_symbol(A,&a);
}
}
break;
case '+':case '-':
case '*':case '/':
topStack_symbol(A,&a);
if (a == '(') {
pushStack_symbol(A,p);
}else{
while (!isPriority(A,p)) {
fun(A,B);
}
pushStack_symbol(A,p);
}
break;
}
}
}
//优先级判断
int isPriority(stackNode_symbol *head, char p){
char s;
int n;
if (stackEmpty_symbol(head)){
return 1;
}
n = topStack_symbol(head,&s);
int a,b;
switch (s) {
case '*':
case '/':a = 3;break;
case '+':
case '-':a = 2;break;
case '(':a = 1;break;
default:a = 0;break;
}
switch (p) {
case '*':
case '/':b = 3;break;
case '+':
case '-':b = 2;break;
default:b = 0;break;
}
if(b > a)
return 1;
return 0;
}
//出栈运算
void fun(stackNode_symbol *A, stackNode_number *B){
double n = 0;
double a,b;
popStack_number(B,&b);
popStack_number(B,&a);
char c;
popStack_symbol(A,&c);
switch (c) {
case '*':n = a * b;break;
case '/':n = a / b;break;
case '+':n = a + b;break;
case '-':n = a - b;break;
}
pushStack_number(B,n);
}
//栈链表初始化
stackNode_number *initStackList_number(){
stackNode_number *p = (stackNode_number*)malloc(sizeof(stackNode_number));
p->next = NULL;
return p;
}
//栈链表判空
int stackEmpty_number(stackNode_number *head){
if(head->next == NULL)
return 1;
return 0;
}
//栈链表入栈
int pushStack_number(stackNode_number *head, double d){
stackNode_number *new;
if ((new = (stackNode_number*)malloc(sizeof(stackNode_number))) == NULL) {
return 0;
}
new->data = d;
new->next = head->next;
head->next = new;
return 1;
}
//栈链表出栈
int popStack_number(stackNode_number *head, double *d){
if (stackEmpty_number(head)) {
return 0;
}
stackNode_number *p = head->next;
*d = p->data;
head->next = p->next;
// free(p);
return 1;
}
//栈链表栈顶元素
int topStack_number(stackNode_number *head, double *d){
if (stackEmpty_number(head)) {
return 0;
}
stackNode_number *p = head->next;
*d = p->data;
return 1;
}
//栈链表初始化
stackNode_symbol *initStackList_symbol(){
stackNode_symbol *p = (stackNode_symbol*)malloc(sizeof(stackNode_symbol));
p->next = NULL;
return p;
}
//栈链表判空
int stackEmpty_symbol(stackNode_symbol *head){
if(head->next == NULL)
return 1;
return 0;
}
//栈链表入栈
int pushStack_symbol(stackNode_symbol *head, char d){
stackNode_symbol *new;
if ((new = (stackNode_symbol*)malloc(sizeof(stackNode_symbol))) == NULL) {
return 0;
}
new->data = d;
new->next = head->next;
head->next = new;
return 1;
}
//栈链表出栈
int popStack_symbol(stackNode_symbol *head, char *d){
if (stackEmpty_symbol(head)) {
return 0;
}
stackNode_symbol *p = head->next;
*d = p->data;
head->next = p->next;
// free(p);
return 1;
}
//栈链表栈顶元素
int topStack_symbol(stackNode_symbol *head, char *d){
if (stackEmpty_symbol(head)) {
return 0;
}
stackNode_symbol *p = head->next;
*d = p->data;
return 1;
}