以前编的,稍微改改又能拿分了,真爽
P.S. gcc里面要链接-lm, e.g. gcc bccn.c -lm
程序代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
struct stackNode {
char data;
struct stackNode *nextPtr;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
void luanlai(StackNodePtr *topPtr , char infix[],int j,char postfix[]) ;
void convertToPostfix(char infix[], char postfix[]);
int isOperator (char c);
int isNumber (char c);
int precedence (char operator1, char operator2);
void push(StackNodePtr *topPtr, char value);
char pop (StackNodePtr *topPtr);
int isEmpty (StackNodePtr topPtr);
void pushNum(StackNodePtr *head, StackNodePtr *tailer, char value);
int popNum(StackNodePtr *head, StackNodePtr *tailer);
void printArray ( char a[]); /*打印数列*/
struct stackPostfix {
double data;
struct stackPostfix *nextPtr;
};
typedef struct stackPostfix StackPostfix;
typedef StackPostfix * StackPostfixPtr;
void pushPostfix(StackPostfixPtr *headPtr, double value);
double popPostfix(StackPostfixPtr *headPtr );
double evaluatePostfixExpression ( char a[]);
double calculate ( double op1 , double op2 , char operate);
void print(StackPostfixPtr headPtr);
int normal;//正常计算期值为1,无优先级为2
void whichCalculator(int *a);
int main(void)
{
int c;
int counter = 1; //fllush (stdin)
whichCalculator(&normal);
while(1)
{
char infix[1001]={'\0'},postfix[1001]={'\0'};
printf("\n> ");
if(counter==1){
while( (c=getchar() ) !='\n' && c!= EOF);
counter++;
}
gets(infix);
convertToPostfix( infix, postfix);
// printArray (postfix); 输出逆波兰表达式
printf("\t%lf",evaluatePostfixExpression(postfix));
printf("\n");
}
return 0;
}
void convertToPostfix(char infix[], char postfix[])
{
int i;
int j;
StackNodePtr head=NULL;
StackNodePtr tailer=NULL;
StackNodePtr topPtr=NULL;
char forPop[2]={0};
char forPopNum[2]={0};
for(i = 0; infix[i]!='\0' ; i++);
infix[i]=')';
infix[i+1] = '\0';
push(&topPtr,'(');
for (j=0; infix[j]!='\0'; j++)
{
if(isNumber(infix[j]))
pushNum(&head, &tailer, infix[j]);
else if(infix[j]=='(')
{
push(&topPtr,'(');
pushNum(&head,&tailer,'0');
}
else if(isOperator(infix[j]))
{
while(head != NULL)
{
forPopNum[0] = popNum(&head,&tailer);
forPopNum[1] = '\0';
strcat( postfix,forPopNum );
}
strcat( postfix," ");
luanlai(&topPtr , infix,j,postfix) ;
push(&topPtr, infix[j]);
}
else if(infix[j]==')')
{
while(head!=NULL)
{
forPopNum[0] = popNum(&head,&tailer);
forPopNum[1] = '\0';
strcat( postfix,forPopNum);
}
strcat( postfix," ");
while( (forPop[0] = pop(&topPtr) )!= '(')
{
forPop[1]='\0';
strcat( postfix,forPop );
strcat( postfix," " );
}
}
}
}
int isOperator (char c)
{
if ( c == 43 || c == 45 || c == 42 || c == 47 || c == 94 || c == 37 )
return 1;
else
return 0;
}
int isNumber (char c)
{
if( isdigit(c) ||c==46 )
return 1;
else
return 0;
}
int precedence (char operator1, char operator2)
{
int i;
int temp[2][2]={{operator1, operator2},{0}};
for(i = 0;i<2 ; i ++)
{
switch (temp[0][i])
{
case 43:
case 45:
temp[1][i]=normal; //normal =1
break;
case 42:
case 47:
case 94:
case 37:
temp[1][i]=2;
break;
case 40:
case 41:
temp[1][i]=-1;
break;
}
}
return temp[1][1]-temp[1][0];
}
void push(StackNodePtr *topPtr, char value)
{
StackNodePtr newPtr;
if( (newPtr=(StackNodePtr) malloc (sizeof( struct stackNode) ) )!= NULL)
{
newPtr->data=value;
newPtr->nextPtr=NULL;
if( *topPtr ==NULL)
{
*topPtr=newPtr;
}
else
{
newPtr->nextPtr=*topPtr;
*topPtr=newPtr;
}
}
else
{
printf("NOT ENOUGH MEMORY\n");
}
}
char pop (StackNodePtr *topPtr)
{
StackNodePtr tempPtr;
char value;
if(*topPtr ==NULL)
{
printf("EMPTY\n");
exit(1);
}
else
{
tempPtr = (*topPtr);
value= tempPtr->data;
(*topPtr)=(*topPtr)->nextPtr;
free(tempPtr);
return value;
}
}
void pushNum(StackNodePtr *head, StackNodePtr *tailer, char value)
{
StackNodePtr newPtr;
if( (newPtr=(StackNodePtr) malloc (sizeof( struct stackNode) ) )!= NULL)
{
newPtr->data=value;
newPtr->nextPtr=NULL;
if( *head==NULL)
{
(*head) = newPtr;
}
else
{
(*tailer)->nextPtr= newPtr;
}
(*tailer)= newPtr;
}
}
int popNum(StackNodePtr *head, StackNodePtr *tailer)
{
int value;
StackNodePtr tempPtr;
if( head !=NULL)
{
value = (*head)->data;
tempPtr = *head;
*head = (*head)->nextPtr;
free(tempPtr);
if(*head ==NULL)
*tailer=NULL;
return value;
}
}
int isEmpty (StackNodePtr topPtr)
{
if (topPtr==NULL)
return 1;
else
return 0;
}
void printArray ( char a[])
{
int i;
for (i=0; a[i]!='\0'; i++ )
printf("%c", a[i]);
}
double evaluatePostfixExpression ( char a[])
{
char b[]=" ";
char *token;
StackPostfixPtr headPtr=NULL;
double x=0.00;
double y=0.00;
token = strtok( a, b);
while (token != NULL)
{
if(isNumber( *token ) )
{
pushPostfix( &headPtr, atof(token) );
}
else
{
x=popPostfix( &headPtr );
y=popPostfix( &headPtr );
pushPostfix(&headPtr,calculate( x , y , (*token) ) );
}
token =strtok (NULL , b);
}
return popPostfix(&headPtr);
}
void pushPostfix(StackPostfixPtr *headPtr, double value)
{
StackPostfixPtr newPtr;
if( (newPtr=(StackPostfixPtr) malloc (sizeof( struct stackPostfix) ) )!= NULL)
{
newPtr->data=value;
newPtr->nextPtr= *headPtr;
*headPtr = newPtr;
}
else
{
printf("NOT ENOUGH MEMORY\n");
}
}
double popPostfix(StackPostfixPtr *headPtr )
{
StackPostfixPtr tempPtr;
double value;
if( (*headPtr) ==NULL)
{
return 0;
}
else
{
tempPtr = (*headPtr);
value= tempPtr->data;
(*headPtr)=(*headPtr)->nextPtr;
free(tempPtr);
return value;
}
}
double calculate ( double op1 , double op2 , char operate)
{
switch (operate)
{
case 43:
return op1+op2;
case 45:
return op2-op1;
case 42:
return op2*op1;
case 47:
return (double)op2/op1;
case 94:
return pow(op2,op1);
case 37:
return (int)(op2)%(int)(op1);
}
return 0;
}
void luanlai(StackNodePtr *topPtr , char infix[],int j,char postfix[])
{
char forPop[2]={'\0'};
forPop[0] = pop(topPtr);
forPop[1]='\0';
if( (precedence(infix[j], forPop[0]))==1 || (precedence(infix[j], forPop[0]))==0)
{
strcat( postfix,forPop );
strcat( postfix," ");
luanlai(topPtr , infix,j,postfix) ;
}
else
push( topPtr, forPop[0]);
}
void print(StackPostfixPtr headPtr)
{
if(headPtr ==NULL)
{
printf("empty");
}
else
{
printf("\nthe stack is:\n");
while(headPtr !=NULL)
{
printf( "%lf-->", headPtr->data);
headPtr=headPtr->nextPtr;
}
}
printf("NULL\n\n");
}
void whichCalculator(int *a)
{
int c;
while(*a!=1 && *a!=2)
{
printf("Select:\n");
printf("1. normal calculator\n");
printf("2. ignore precedence\n? ");
scanf("%d",a);
if( (! (isdigit(*a) ) ) && (*a!=1 &&*a!=2) )
{
printf("\n*** Error: select 1 or 2! ***\n\n" );
while( (c=getchar() ) !='\n' && c!=EOF);
whichCalculator(a);
break;
}
}
}
[
本帖最后由 oszc 于 2011-7-3 00:55 编辑 ]