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

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

再不斩



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

5come5帮你背单词 [ hijack /'haid3əæk/ vt. 动持,拦路抢动 ]


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

以前大二,上数据结构的时候,书上提到了将式子,比如"-(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 | [楼 主]
再不斩



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

5come5帮你背单词 [ rim /rim/ n. 边,外缘 ]


感觉这个页面太长了怎么。。。  
顶端 Posted: 2007-10-28 14:35 | [1 楼]
不会游泳的鱼



性别: 帅哥 状态: 该用户目前不在线
等级: 栋梁之材
发贴: 514
威望: 0
浮云: 1117
在线等级:
注册时间: 2007-08-29
最后登陆: 2008-06-07

5come5帮你背单词 [ transact /træn'zækt/ vt. 交易,办理,处理 ]


强,顶
顶端 Posted: 2007-10-28 16:14 | [2 楼]
路客与刀客



性别: 帅哥 状态: 该用户目前不在线
等级: 希望之光
家族: 梦魇图腾
发贴: 1980
威望: 0
浮云: 1186
在线等级:
注册时间: 2007-01-02
最后登陆: 2008-06-29

5come5帮你背单词 [ lecturer /'lektərə/ n. 讲演者,讲师 ]


也发个计算器。
附件: DlgCalc.rar (75 K) 下载次数:26

顶端 Posted: 2007-10-28 18:34 | [3 楼]
terry



性别: 帅哥 状态: 该用户目前不在线
等级: 栋梁之材
家族: 菠韬汹勇
发贴: 768
威望: 0
浮云: 1112
在线等级:
注册时间: 2005-11-01
最后登陆: 2010-08-16

5come5帮你背单词 [ prototype /'prəutətaip/ n. 原型,样品 ]


Quote:
引用第3楼路客与刀客于2007-10-28 18:34发表的  :
也发个计算器。

这个和楼主写的意思不一样哈。。。
顶端 Posted: 2007-10-28 18:37 | [4 楼]
mini



性别: 帅哥 状态: 该用户目前不在线
头衔: 实力派!
等级: 人见人爱
发贴: 3513
威望: 0
浮云: 2141
在线等级:
注册时间: 2006-02-18
最后登陆: 2013-01-12

5come5帮你背单词 [ cherry /'teri/ n. 樱桃 ]


蝈蝈真是强人啊
顶端 Posted: 2007-10-28 18:40 | [5 楼]
albert





性别: 保密 状态: 该用户目前不在线
等级: 栋梁之材
家族: 唯war独尊
发贴: 634
威望: 0
浮云: 1116
在线等级:
注册时间: 2005-10-04
最后登陆: 2012-02-12

5come5帮你背单词 [ reject /ri'd3ekt/ vt. 拒绝接受,抵制驳回 ]


LZ如果学了编译原理的话就知道其实这种计算器可以实现的更简洁一些了。
本帖最近评分记录:
  • 浮云:-3(zhd32) 不要挖矿哈
  • 顶端 Posted: 2007-11-17 23:27 | [6 楼]
    一米阳光



    性别: 美女 状态: 该用户目前不在线
    头衔: 把忧伤丢进风里……
    等级: 荣誉会员
    家族: 单身贵族
    发贴: 4109
    威望: 3
    浮云: 285
    在线等级:
    注册时间: 2007-09-09
    最后登陆: 2010-01-23

    5come5帮你背单词 [ shiny /'aini/ a. 照耀闪烁的,发亮的,晴朗的 ]


    好长,跟附件里的计算器有什么区别吗?
    顶端 Posted: 2007-11-17 23:31 | [7 楼]
    暗火



    性别: 帅哥 状态: 该用户目前不在线
    等级: 鹤立鸡群
    家族: 东北一家人
    发贴: 1220
    威望: 0
    浮云: 1158
    在线等级:
    注册时间: 2007-03-08
    最后登陆: 2011-05-08

    5come5帮你背单词 [ revelation /revi'leiən/ n. 揭示,透露,显示,被揭示的真相,新发现 ]


    炫耀帖??  
    顶端 Posted: 2007-11-17 23:33 | [8 楼]
    依风



    性别: 帅哥 状态: 该用户目前不在线
    头衔: 左脸忧愁,右脸微笑
    等级: 成就辉煌
    家族: 梦魇图腾
    发贴: 12943
    威望: 5
    浮云: 1345
    在线等级:
    注册时间: 2007-04-25
    最后登陆: 2010-09-17

    5come5帮你背单词 [ spectrum /'spektrəm/ n. 光谱,频谱,领域,范围 ]


    正好有个创新学分是这个
    顶端 Posted: 2007-11-18 12:11 | [9 楼]
    kingge



    性别: 帅哥 状态: 该用户目前不在线
    头衔: 自信~~~!
    等级: 人见人爱
    家族: Westlife Family
    发贴: 2480
    威望: 0
    浮云: 1105
    在线等级:
    注册时间: 2007-09-11
    最后登陆: 2009-05-06

    5come5帮你背单词 [ food /fu:d/ n. 食物 ]


    厉害啊,有时间也好看看
    顶端 Posted: 2007-11-18 12:14 | [10 楼]
    lsy



    性别: 帅哥 状态: 该用户目前不在线
    头衔: 信我者,得永生
    等级: 人见人爱
    家族: YD一族
    发贴: 2226
    威望: 5
    浮云: 1591
    在线等级:
    注册时间: 2006-11-29
    最后登陆: 2009-10-01

    5come5帮你背单词 [ petrol /'petrəl/ n. 汽油 ]


    都是牛人
    顶端 Posted: 2007-11-18 12:43 | [11 楼]
    est





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

    5come5帮你背单词 [ curriculum /kə'rikjuləm/ n. (学校、专业的)全部课程,(取得毕业资格的)必修课程 ]




    还是希望了脚本语言

    直接eval()
    顶端 Posted: 2007-11-18 14:11 | [12 楼]
    allenpower



    性别: 帅哥 状态: 该用户目前不在线
    头衔: 我素新人~~
    等级: 不日成名
    发贴: 406
    威望: 0
    浮云: 497
    在线等级:
    注册时间: 2007-04-15
    最后登陆: 2011-12-02

    5come5帮你背单词 [ geography /d3əi'ogrəfi/ n. 地理(学) ]


    如果想做底层,还要继续加油~
    顶端 Posted: 2007-11-18 15:47 | [13 楼]
    madjjyy



    性别: 帅哥 状态: 该用户目前不在线
    头衔: 笔记本被盗.此人已死.
    等级: 动漫联萌
    家族: Galgame有爱委员会
    发贴: 1966
    威望: 0
    浮云: 178
    在线等级:
    注册时间: 2005-11-13
    最后登陆: 2009-05-10

    5come5帮你背单词 [ civilise // vt. 使文明,使开化 ]


    Quote:
    引用第6楼albert于2007-11-17 23:27发表的  :
    LZ如果学了编译原理的话就知道其实这种计算器可以实现的更简洁一些了。

    貌似不算挖矿吧?
    顶端 Posted: 2007-11-18 22:51 | [14 楼]
    我来我网·5come5 Forum » 程序员之家

    Total 0.011900(s) query 5, Time now is:04-27 17:31, Gzip enabled
    Powered by PHPWind v5.3, Localized by 5come5 Tech Team, 黔ICP备16009856号