我来我网
https://5come5.cn
 
您尚未 登录  注册 | 菠菜 | 软件站 | 音乐站 | 邮箱1 | 邮箱2 | 风格选择 | 更多 » 
 

本页主题: 花了两天时间终于将“计算器程序”完成。 显示签名 | 打印 | 加为IE收藏 | 收藏主题 | 上一主题 | 下一主题

再不斩



性别: 帅哥 状态: 该用户目前不在线
等级: 鹤立鸡群
发贴: 1414
威望: 0
浮云: 1413
在线等级:
注册时间: 2005-12-23
最后登陆: 2009-04-26

5come5帮你背单词 [ petroleum /pi'trəuljəm/ n. 石油 ]


花了两天时间终于将“计算器程序”完成。

以前大二,上数据结构的时候,书上提到了将式子,比如"-(100+52)*2"输入,然后就可以输出计算结果的算法实现,可一直没试,没想到实现起来还真麻烦,有许多容错机制需要注意,这是我到现在为止没发现任何使用限制(当然运算符只限于+、-、*、/和括号运算符)的版本了,拿来分享,望不吝赐教。
#include<stdio.h>
#include<stdlib.h>

#define INPUT_LENGTH 100
#define MAX_INT_LENGTH 5

struct operates {
    char operate;
    struct operates * next_operator;
};
struct operands{
    int operand;
    struct operands * next_operand;
};


int separator(char *,struct operates **,struct operands **);
int calculate(struct operates *,struct operands *);
int ganerate(int,int,char);
int asc_to_int(char *,int *actual_int);
void main()
{
    char whether_to_exit,input_string[INPUT_LENGTH];
    struct operates *head_of_operators;
    struct operands * head_of_operands;
    int the_result;


    whether_to_exit='n';
    while(whether_to_exit!='q' && whether_to_exit!='Q')    //用于判断一次计算完毕,用户是否要进行下一次计算。
    {
        printf("Please input the formula you wanna calculate:\n");
        gets(input_string);
        if(separator(input_string,&head_of_operators,&head_of_operands)==-1)
        {
            printf("You have input an invalid formula,please try again\n");
            continue;
        }

        the_result=calculate(head_of_operators,head_of_operands);
        printf("The result of the formula above is:%d\n",the_result);
    }

    printf("Thank you for using my programme;)");
}

int separator(char *input_string,struct operates **head_of_operators,struct operands **head_of_operands)//提取字符串中的操作数和操作符,不进行检错。
{
    struct operates *op1;
    struct operands *op2;
    int int_from_string,mark_for_minor,return_from_asc_to_int,counter_for_left,counter_for_right;
    char tmp_char,phase_char,*tmp_ptr;

    op1=op2=phase_char=NULL;
    mark_for_minor=counter_for_left=counter_for_right=0;
    tmp_ptr=input_string;
    ///////检错部分       
    tmp_char=*tmp_ptr;
    if(tmp_char=='+' || tmp_char=='*' || tmp_char=='/' || (tmp_char=='-' && (*(input_string+1)!='(' && (*(input_string+1)<'0' || *(input_string+1)>'9'))))
        return -1;
    while(*(input_string+1)!=NULL)
        input_string++;

    if(*input_string!=')' && !(*input_string>='0' && *input_string<='9') && *input_string!=' ')
        return -1;
    /////////检错完结
    /////////以下对以负号打头的式子进行处理:
    if(*tmp_ptr=='-')
    {
        op2=(struct operands *)malloc(sizeof(struct operands));
        *head_of_operands=op2;
        op2->next_operand=NULL;
        op2->operand=0;
    }
    //////处理结束
    while(*tmp_ptr!=NULL)
    {
        tmp_char=*tmp_ptr;
        if(tmp_char==' ')
        {
            tmp_ptr++;
            continue;
        }
        if(tmp_char >='0' && tmp_char <='9')//提取其中数字,然后将缓冲区指针向前推进。
        {
            phase_char=NULL;
            if((return_from_asc_to_int=asc_to_int(tmp_ptr,&int_from_string))==-1)
            {
                printf("Too large int.\n");
                return -1;
            }
            tmp_ptr+=return_from_asc_to_int;
            if(op2==NULL)
            {
                op2=(struct operands*)malloc(sizeof(struct operands));
                if(mark_for_minor==1)
                {
                    op2->operand=0-int_from_string;
                    mark_for_minor=0;
                }
                else
                    op2->operand=int_from_string;
                op2->next_operand=NULL;
                *head_of_operands=op2;
            }
            else
            {
                op2->next_operand=(struct operands*)malloc(sizeof(struct operands));
                op2=op2->next_operand;
                if(mark_for_minor==1)
                {
                    op2->operand=0-int_from_string;
                    mark_for_minor=0;
                }
                else
                    op2->operand=int_from_string;
                op2->next_operand=NULL;
            }
        }
        else if(tmp_char=='+' || tmp_char == '-' || tmp_char == '*' || tmp_char == '/' || tmp_char == '(' || tmp_char == ')')
        {

            //////////以下是检错部分:
            if(tmp_char=='(')
                counter_for_left++;
            if(tmp_char==')')
                counter_for_right++;
            if(phase_char!=NULL)
            {
                if(!((tmp_char=='(' && phase_char!=')') || (phase_char=='(' && tmp_char=='-') || (phase_char==')' && tmp_char!='(')))//当两个运算符连续出现时,只能是这几种情况:"(-","+(","-(","*(","/(",")+"...
                    return -1;


            }
            phase_char=tmp_char;
            //////////检错结束
            if(op1==NULL)
            {
                op1=(struct operates *) malloc(sizeof(struct operates));
                op1->operate=tmp_char;
                op1->next_operator=NULL;
                *head_of_operators=op1;
            }
            else
            {
                op1->next_operator=(struct operates *) malloc( sizeof(struct operates));
                op1=op1->next_operator;
                op1->operate=tmp_char;
                op1->next_operator=NULL;

            }
            tmp_ptr++;
            if(tmp_char=='(' && *(tmp_ptr) == '-')
            {
                tmp_ptr++;
                mark_for_minor=1;
            }

        }
        else
        {
            printf("Invalid char(s)!\n");
            return -1;
        }
    }
    //////检错部分:
    if(counter_for_left!=counter_for_right)
        return -1;
}
int calculate(struct operates *head_of_operators,struct operands *head_of_operands)
{
    struct operands *operand_polor;
    struct operates *operator_polor,*pre;


    operand_polor=head_of_operands;
    pre=operator_polor=head_of_operators;
   
    if(head_of_operators->next_operator!=NULL && head_of_operators->operate=='(' && head_of_operators->next_operator->operate==')')
    {
        if(head_of_operators->next_operator->next_operator!=NULL)
            return calculate(head_of_operators->next_operator->next_operator,head_of_operands);
        else
            return head_of_operands->operand;
    }

    if(head_of_operators->next_operator==NULL)
        return ganerate(operand_polor->operand,operand_polor->next_operand->operand,head_of_operators->operate);
    else
    {
        while(operator_polor->next_operator!=NULL && (operator_polor->operate=='(' || operator_polor->next_operator->operate=='(' || (operator_polor->operate=='+' || operator_polor->operate=='-') && (operator_polor->next_operator->operate=='*' || operator_polor->next_operator->operate=='/')))
        {
            if(operator_polor->operate=='(' && operator_polor->next_operator->operate==')')
            {
                pre->next_operator=operator_polor->next_operator->next_operator;
                return calculate(head_of_operators,head_of_operands);
            }

            else
            {
                pre=operator_polor;

                if(operator_polor->operate!='(')
                    operand_polor=operand_polor->next_operand;
                operator_polor=operator_polor->next_operator;
            }
        }

        operand_polor->operand=ganerate(operand_polor->operand,operand_polor->next_operand->operand,operator_polor->operate);
        operand_polor->next_operand=operand_polor->next_operand->next_operand;

        pre->next_operator=operator_polor->next_operator;
        if(operator_polor==head_of_operators)
            return calculate(head_of_operators->next_operator,head_of_operands);
        else
            return calculate(head_of_operators,head_of_operands);
    }
   

}
int ganerate(int op1,int op2,char operate)
{
    switch(operate)
    {
    case '+':return(op1+op2);
    case '-':return(op1-op2);
    case '*':return(op1*op2);
    case '/':return(op1/op2);
    }

}

int asc_to_int(char *input_string,int *actual_int)
{
    int j;
    char tmp_for_int[MAX_INT_LENGTH+1],*tmp_ptr;
    j=0;
    tmp_ptr=input_string;
    while(*tmp_ptr>='0' && *tmp_ptr<='9')
    {
        if(j > MAX_INT_LENGTH-1)
            return -1;
        tmp_for_int[j]=*tmp_ptr;
        tmp_ptr++;
        j++;
    }

    tmp_for_int[j]='\0';
    *actual_int=atoi(tmp_for_int);
    return j;
}
以下是打好包的程序,解压可直接运行:
描述:可执行程序(无毒版)
附件: FormulaTrans.rar (26 K) 下载次数:43

顶端 Posted: 2007-10-28 14:31 | [楼 主]
est





性别: 帅哥 状态: 该用户目前不在线
等级: 荣誉会员
发贴: 6578
威望: 3
浮云: 431
在线等级:
注册时间: 2006-10-14
最后登陆: 2018-07-05

5come5帮你背单词 [ sweat /swet/ n. 汗(水);v. (使)出汗 ]




还是希望了脚本语言

直接eval()
顶端 Posted: 2007-11-18 14:11 | [1 楼]
我来我网·5come5 Forum » 程序员之家

Total 0.013622(s) query 6, Time now is:11-22 03:26, Gzip enabled
Powered by PHPWind v5.3, Localized by 5come5 Tech Team, 黔ICP备16009856号