分享|代码
66
14 小时前
14 小时前
发布于 中国

测试案例不可见

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define OK 1 //正确或成功

#define ERROR 0 //错误或失败

typedef int Status;

// 请在这里补充代码,此处可写结构体、函数、全局变量等

/********** Begin *********/

#include <ctype.h>

#define MAX_LEN 256

#define MAX_STACK 100

typedef struct{

char data[MAX_STACK];

int top;

}BracketStack;

typedef struct{

union{

float num_data[MAX_STACK];

char op_data[MAX_STACK];

}data;

int top;

int type;

}Stack;

void InitStack(Stack *s,int type){

s->top=-1;

s->type=type;

}

void InitBracketStack(BracketStack *s){

s->top=-1;

}

Status pushStack(Stack *s,void *val){

if(s->top>=MAX_STACK-1) return ERROR;

s->top++;

if(s->type==0){

s->data.num_data[s->top]=*(float*)val;

}

else if(s->type==1){

s->data.op_data[s->top]=*(char*)val;

}

return OK;

}

Status popStack(Stack *s,void *val){

if(s->top<0) return ERROR;

if(s->type==0){

*(float*)val=s->data.num_data[s->top];

}

else if(s->type==1){

*(char*)val=s->data.op_data[s->top];

}

s->top--;

return OK;

}

Status getTopStack(Stack *s,void *val){

if(s->top<0) return ERROR;

if(s->type==0){

*(float*)val=s->data.num_data[s->top];

}

else if(s->type==1){

*(char*)val=s->data.op_data[s->top];

}

return OK;

}

Status pushBracket(BracketStack *s,char c){

if(s->top>=MAX_STACK-1) return ERROR;

s->data[++s->top]=c;

return OK;

}

Status popBracket(BracketStack *s,char*c){

if(s->top<0) return ERROR;

*c=s->data[s->top--];

return OK;

}

Status getTopBracket(BracketStack *s,char *c){

if(s->top<0)return ERROR;

*c=s->data[s->top];

return OK;

}

int isOperator(char c){

return c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='['||c==']'||c=='{'||c=='}';

}

int isLeftBracket(char c){

return c=='('||c=='['||c=='{';

}

int isRightBracket(char c){

return c==')'||c==']'||c=='}';

}

char matchBracket(char right){

switch(right){

case')':return '(';

case']':return '[';

case'}':return '{';

default:return 0;

}

}

int getPriority(char op){

if(isLeftBracket(op)) return 0;

switch(op){

case'+':

case'-':return 1;

case'*':

case'/':return 2;

default:return -1;

}

}

void normalizeExpr(char *src,char *dst){

int j=0;

int len=strlen(src);

for(int i=0;i<len;i++){

if(src[i]==' '||src[i]=='\t')continue;

if(src[i]=='['||src[i]=='{'){

dst[j++]='(';

}

else if(src[i]==']'||src[i]=='}'){

dst[j++]=')';

}

else{

dst[j++]=src[i];

}

}

dst[j]='\0';

}

Status checkExprValid(char *expr){

BracketStack bStack;

InitBracketStack(&bStack);

int len=strlen(expr);

int lastIsOp=1;

int lastIsBracket=1;

int dotCount=0;

for(int i=0;i<len;i++){

char c=expr[i];

if(c==' '||c=='\t')continue;

if(!((c>='0'&&c<='9')||isOperator(c)||c=='.')){

return ERROR;

}

if(isLeftBracket(c)){

pushBracket(&bStack,c);

lastIsOp=1;

lastIsBracket=1;

dotCount=0;

continue;

}

if(isRightBracket(c)){

char top;

if(getTopBracket(&bStack,&top)==ERROR||top!=matchBracket(c)){

return ERROR;

}

popBracket(&bStack,&top);

lastIsOp=0;

lastIsBracket=0;

dotCount=0;

continue;

}

if(isOperator(c)&&!isLeftBracket(c)&&!isRightBracket(c)){

if(lastIsOp&&!(c=='-'&&(lastIsBracket||i==0))){

return ERROR;

}

lastIsOp=1;

lastIsBracket=0;

dotCount=0;

continue;

}

if((c>='0'&&c<='9')||c=='.'){

if(c=='.'){

dotCount++;

if(dotCount>1)return ERROR;

if(i==0||(i+1>=len||!isdigit(expr[i+1])))return ERROR;

}

lastIsOp=0;

lastIsBracket=0;

continue;

}

}

if(bStack.top!=-1)return ERROR;

if(lastIsOp)return ERROR;

return OK;

}

Status calculateBinary(float a,char op,float b,float *res){

switch(op){

case'+':*res=a+b;

break;

case'-':*res=a-b;

break;

case'*':*res=a*b;

break;

case'/':

if(b<1e-6&&b>-1e-6)return ERROR;

*res=a/b;

break;

default:return ERROR;

}

return OK;

}

/********** End **********/

Status calculator(char line[],float &value)

//line:表达式,value:存表达式的值

//函数功能:计算表达式line的值

//如果表达式line的值被正确计算,返回OK;否则返回Error

{

// 请在这里补充代码

/********** Begin *********/

if(checkExprValid(line)==ERROR){

return ERROR;

}

char normExpr[MAX_LEN];

normalizeExpr(line,normExpr);

Stack numStack,opStack;

InitStack(&numStack,0);

InitStack(&opStack,1);

int i=0;

int len=strlen(normExpr);

while(i<len){

char c=normExpr[i];

if(c==' '||c=='\t'){

i++;

continue;

}

if(isdigit(c)||(c=='-'&&(i==0||normExpr[i-1]=='('||isOperator(normExpr[i-1])&&!isRightBracket(normExpr[i-1])))||(c=='.'&&i>0&&isdigit(normExpr[i-1]))){

int isNegative=0;

float num=0.0f;

int decimal=0;

float decFactor=0.1f;

if(c=='-'){

isNegative=1;

i++;

if(i>=len)return ERROR;

c=normExpr[i];

}

while(i<len&&isdigit(normExpr[i])){

num=num*10+(normExpr[i]-'0');

i++;

}

if(i<len&&normExpr[i]=='.'){

decimal=1;

i++;

while(i<len&&isdigit(normExpr[i])){

num+=(normExpr[i]-'0')*decFactor;

decFactor*=0.1f;

i++;

}

if(decimal&&(i==len||!isdigit(normExpr[i-1])))return ERROR;

}

if(isNegative)num=-num;

if(!pushStack(&numStack,&num))return ERROR;

continue;

}

if(isOperator(c)){

if(isLeftBracket(c)){

char op='(';

if(!pushStack(&opStack,&op)) return ERROR;

i++;

}else if(isRightBracket(c)){

char op;

while(getTopStack(&opStack,&op)==OK&&op!='('){

float b,a,res;

if(!popStack(&numStack,&b)||!popStack(&numStack,&a))return ERROR;

if(!calculateBinary(a,op,b,&res))return ERROR;

if(!pushStack(&numStack,&res))return ERROR;

popStack(&opStack,&op);

}

if(!popStack(&opStack,&op)||op!='(')return ERROR;

i++;

}

else{

char topOp;

while(getTopStack(&opStack,&topOp)==OK&&getPriority(topOp)>=getPriority(c)){

float b,a,res;

if(!popStack(&numStack,&b)||!popStack(&numStack,&a))return ERROR;

if(!calculateBinary(a,topOp,b,&res))return ERROR;

if(!pushStack(&numStack,&res))return ERROR;

popStack(&opStack,&topOp);

}

if(!pushStack(&opStack,&c))return ERROR;

i++;

}

continue;

}

}

char op;

while(getTopStack(&opStack,&op)==OK){

float b,a,res;

if(!popStack(&numStack,&b)||!popStack(&numStack,&a))return ERROR;

if(!calculateBinary(a,op,b,&res))return ERROR;

if(!pushStack(&numStack,&res))return ERROR;

popStack(&opStack,&op);

}

if(numStack.top!=0)return ERROR;

getTopStack(&numStack,&value);

return OK;

/********** End **********/

}

Status readFile(char filename[])

//filename:文件名(txt文件)

//函数功能:读入filename文件中的表达式(一行存储一个表达式,文件中可能有多行),针对每个表达式,调用calculator执行表达式的计算

//输出表达式的计算结果,输出格式如下:

//(1)若表达式的值被正确计算,则输出格式为:printf("表达式%s的计算结果为:%.2f\n",X,XX);

//(2)若表达式错误,不能被正确计算,则输出格式为:printf("表达式%s错误\n",X);

//若文件中的所有表达式都被处理则函数返回OK,否则返回ERROR

{

// 请在这里补充代码

/********** Begin *********/

FILE *fp=fopen(filename,"r");

if(fp==NULL)return ERROR;

char line[MAX_LEN];

while(fgets(line,MAX_LEN,fp)!=NULL){

size_t len=strlen(line);

if(len>0){

if(line[len-1]=='\n')line[len-1]='\0';

if(len>1&&line[len-2]=='\r')line[len-2]='\0';

}

if(strlen(line)==0)continue;

float value;

if(calculator(line,value)==OK){

printf("表达式%s的计算结果为:%.2f\n",line,value);

}

else{

printf("表达式%s错误\n",line);

}

}

fclose(fp);

return OK;

/********** End **********/

}

int main()

{

char filename[100];

//请输入要读取的文件名:

scanf("%s", filename);

if(!readFile(filename)){

printf("输入文件不存在或I/O错误");

}

return 0;

}

评论 (0)