python

来源:互联网 发布:win10输入法切换软件 编辑:程序博客网 时间:2024/06/18 08:35

问题:

公司举办了一次TDD的研讨会,讨论的程序为实现计算器的+-*/()。

要求采用TDD的方式进行程序的开发,并且程序是稳定的。

TDD的例子:

str0 = '1 +2 'str4 = '10+22'str5 = '10+22-33'str6 = '10+22-33*44+55 /66 'str1 = '1+(2-3)*4/5'str2 = '10+((20-3)*4)/5'str3 = '1+(((2-3)*4)/5)'strn = '100+5-2*(4*5+1)+((7/8+6)*9/5-3)'str_err = 'alsdjfk'

解决方案:

电脑的计算方式和人的大脑的计算方式类似。

1、先找到左括号和右括号,然后计算里面的值。

2、采用递归,完成所有括号的计算,并将计算得出的值替换掉括号。

3、找到*/,并按顺序进行。

4、找到+-,并按顺序进行。

知识点:

1、

return mulordev(list1) # python迭代的坑,每一次迭代必须有返回值
2、

list2 = re.split(r'[+-/*/]', str6)

讨论:

1、暂不考虑浮点计算。

2、计算的程序均采用递归,括号做一次,乘除做一次,加减做一次,有点冗余。

3、比较研讨会上采用C语言来实现。比较:C更加严谨,层次感强。python更加直观,通俗易懂。


源代码:

# coding:utf-8import randomimport reflag_change = 0 # 用于处理括号def new_list(str0):    '''生成可计算的字符串'''    # list2 = re.split(r'[+-/*/]', str6)    # for m in range(0,len(list2),1):    #     list2[m] = list2[m].strip()    # print list2    list0 = list(str0)    length = len(list0)    num = 0    list_new = []    for m in range(0,length,1):        if '0'<=list0[m]<='9':            flag_change = 1            num = 10*num +int(list0[m])        if '+'==list0[m] or '-'==list0[m] or '*'==list0[m] or '/'==list0[m] or '('==list0[m] or ')'==list0[m]:            if 1 == flag_change:                flag_change = 0                list_new.append(str(num))                num = 0            list_new.append(list0[m])        if length-1 == m and ')'!=list0[m]: # 不以右括号结尾            list_new.append(str(num))    return list_newdef mulordev(list1):    '''计算乘除'''    print list1    length = len(list1)    for m in range(0,length,1):        if length-1 == m:            return list1        if '*' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) * int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if '/' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) / int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break    return mulordev(list1) # python迭代的坑,每一次迭代必须有返回值def addormin(list1):    '''计算加减'''    print list1    length = len(list1)    for m in range(0, length, 1):        if '+' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) + int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if '-' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) - int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if length - 1 == m:            return list1    return addormin(list1) # python迭代的坑,每一次迭代必须有返回值def brackets(list1):    '''计算括号'''    print list1    length = len(list1)    if '(' not in list1 and ')' not in list1:        return list1    flag_left = 0    flag_right = 0    for m in range(0,length,1):        if '(' == list1[m]:            flag_left = m        if ')' == list1[m]:            flag_right = m            list1[flag_left] = addormin(mulordev(list1[flag_left+1 : flag_right]))[0]            del list1[flag_left+1 : flag_right+1]            break    return brackets(list1)str0 = '1 +2 'str4 = '10+22'str5 = '10+22-33'str6 = '10+22-33*44+55 /66 'str1 = '1+(2-3)*4/5'str2 = '10+((20-3)*4)/5'str3 = '1+(((2-3)*4)/5)'strn = '100+5-2*(4*5+1)+((7/8+6)*9/5-3)'str_err = 'alsdjfk'str_cal = str_errprint '字符串为:%s \n计算结果为:%d\n' % (str_cal, int(addormin(mulordev(brackets(new_list(str_cal))))[0]))'''['100', '+', '5', '-', '2', '*', '(', '4', '*', '5', '+', '1', ')', '+', '(', '(', '7', '/', '8', '+', '6', ')', '*', '9', '/', '5', '-', '3', ')']['4', '*', '5', '+', '1']['20', '+', '1']['20', '+', '1']['21']['100', '+', '5', '-', '2', '*', '21', '+', '(', '(', '7', '/', '8', '+', '6', ')', '*', '9', '/', '5', '-', '3', ')']['7', '/', '8', '+', '6']['0', '+', '6']['0', '+', '6']['6']['100', '+', '5', '-', '2', '*', '21', '+', '(', '6', '*', '9', '/', '5', '-', '3', ')']['6', '*', '9', '/', '5', '-', '3']['54', '/', '5', '-', '3']['10', '-', '3']['10', '-', '3']['7']['100', '+', '5', '-', '2', '*', '21', '+', '7']['100', '+', '5', '-', '2', '*', '21', '+', '7']['100', '+', '5', '-', '42', '+', '7']['100', '+', '5', '-', '42', '+', '7']['105', '-', '42', '+', '7']['63', '+', '7']['70']字符串为:100+5-2*(4*5+1)+((7/8+6)*9/5-3)计算结果为:70'''******** TDD - 第一次 ****************# coding:utf-8import randomdef add(a,b):    return int(a) + int(b)def min(a,b):    return int(a) - int(b)def mul(a,b):    return int(a) * int(b)def dev(a,b):    return int(a) / int(b)str0 = '1+2'str4 = '10+22'str1 = '1+(2-3)*4/5'str2 = '10+(20-3)*4/5'str3 = '1+2-3*4/5'result = 0list0 = list(str4)print list0length = len(list0)num = 0list_new = []for m in range(0,length,1):    if '0'<=list0[m]<='9':        num = 10*num +int(list0[m])    if '+'==list0[m] or '-'==list0[m]:        list_new.append(str(num))        list_new.append(list0[m])        num = 0    if length-1 == m:        list_new.append(str(num))print list_newlength = len(list_new)for m in range(0,length,1):    if '+' == list_new[m]:        print m        list_new[m-1] = str(int(list_new[m-1]) + int(list_new[m+1]))        del list_new[m]        del list_new[m]        break        print list_new************ TDD - 第二次 **************************str0 = '1+2'str4 = '10+22'str5 = '10+22-33'str1 = '1+(2-3)*4/5'str2 = '10+(20-3)*4/5'str3 = '1+2-3*4/5'result = 0list0 = list(str5)print list0length = len(list0)num = 0list_new = []for m in range(0,length,1):    if '0'<=list0[m]<='9':        num = 10*num +int(list0[m])    if '+'==list0[m] or '-'==list0[m]:        list_new.append(str(num))        list_new.append(list0[m])        num = 0    if length-1 == m:        list_new.append(str(num))print list_newlength = len(list_new)for m in range(0,length,1):    if '+' == list_new[m]:        list_new[m+1] = str(int(list_new[m-1]) + int(list_new[m+1]))    if '-' == list_new[m]:        list_new[m + 1] = str(int(list_new[m-1]) - int(list_new[m+1]))print list_new[-1]****************** TDD - 第三次 ********************************************str0 = '1 +2 'str4 = '10+22'str5 = '10+22-33'str6 = '10+22-33*44+55 /66 'str1 = '1+(2-3)*4/5'str2 = '10+(20-3)*4/5'str3 = '1+2-3*4/5'result = 0list2 = re.split(r'[+-/*/]', str6)for m in range(0,len(list2),1):    list2[m] = list2[m].strip()print list2list0 = list(str6)print list0length = len(list0)num = 0list_new = []for m in range(0,length,1):    if '0'<=list0[m]<='9':        num = 10*num +int(list0[m])    if '+'==list0[m] or '-'==list0[m] or '*'==list0[m] or '/'==list0[m]:        list_new.append(str(num))        list_new.append(list0[m])        num = 0    if length-1 == m:        list_new.append(str(num))print list_newprint '***'def mulordev(list1):    print list1    length = len(list1)    for m in range(0,length,1):        if length-1 == m:            return list1        if '*' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) * int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if '/' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) / int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break    return mulordev(list1) # python迭代的坑,每一次迭代必须有返回值def addormin(list1):    print list1    length = len(list1)    for m in range(0, length, 1):        if '+' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) + int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if '-' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) - int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if length - 1 == m:            return list1    return addormin(list1) # python迭代的坑,每一次迭代必须有返回值print addormin(mulordev(list_new))*************** TDD - 第四次 *******************************# coding:utf-8import randomimport redef new_list(str0):    '''生成可计算的字符串'''    # list2 = re.split(r'[+-/*/]', str6)    # for m in range(0,len(list2),1):    #     list2[m] = list2[m].strip()    # print list2    list0 = list(str0)    length = len(list0)    num = 0    list_new = []    for m in range(0,length,1):        if '0'<=list0[m]<='9':            num = 10*num +int(list0[m])        if '+'==list0[m] or '-'==list0[m] or '*'==list0[m] or '/'==list0[m]:            list_new.append(str(num))            list_new.append(list0[m])            num = 0        if length-1 == m:            list_new.append(str(num))    return list_newdef mulordev(list1):    '''计算乘除'''    # print list1    length = len(list1)    for m in range(0,length,1):        if length-1 == m:            return list1        if '*' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) * int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if '/' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) / int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break    return mulordev(list1) # python迭代的坑,每一次迭代必须有返回值def addormin(list1):    '''计算加减'''    # print list1    length = len(list1)    for m in range(0, length, 1):        if '+' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) + int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if '-' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) - int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if length - 1 == m:            return list1    return addormin(list1) # python迭代的坑,每一次迭代必须有返回值str0 = '1 +2 'str4 = '10+22'str5 = '10+22-33'str6 = '10+22-33*44+55 /66 'str1 = '1+(2-3)*4/5'str2 = '10+(20-3)*4/5'str3 = '1+2-3*4/5'result = 0str_cal = str6print '字符串为:%s \n计算结果为:%d\n' % (str_cal, int(addormin(mulordev(new_list(str_cal)))[0]))****************** TDD - 第五次 *******************************************************# coding:utf-8import randomimport reflag_change = 0 # 用于处理括号def new_list(str0):    '''生成可计算的字符串'''    # list2 = re.split(r'[+-/*/]', str6)    # for m in range(0,len(list2),1):    #     list2[m] = list2[m].strip()    # print list2    list0 = list(str0)    length = len(list0)    num = 0    list_new = []    for m in range(0,length,1):        if '0'<=list0[m]<='9':            flag_change = 1            num = 10*num +int(list0[m])        if '+'==list0[m] or '-'==list0[m] or '*'==list0[m] or '/'==list0[m] or '('==list0[m] or ')'==list0[m]:            if 1 == flag_change:                flag_change = 0                list_new.append(str(num))                num = 0            list_new.append(list0[m])        if length-1 == m and ')'!=list0[m]: # 不以右括号结尾            list_new.append(str(num))    return list_newdef mulordev(list1):    '''计算乘除'''    print list1    length = len(list1)    for m in range(0,length,1):        if length-1 == m:            return list1        if '*' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) * int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if '/' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) / int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break    return mulordev(list1) # python迭代的坑,每一次迭代必须有返回值def addormin(list1):    '''计算加减'''    print list1    length = len(list1)    for m in range(0, length, 1):        if '+' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) + int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if '-' == list1[m]:            list1[m + 1] = str(int(list1[m - 1]) - int(list1[m + 1]))            del list1[m - 1]            del list1[m - 1]            break        if length - 1 == m:            return list1    return addormin(list1) # python迭代的坑,每一次迭代必须有返回值def brackets(list1):    '''计算括号'''    print list1    length = len(list1)    flag_left = 0    flag_right = 0    for m in range(0,length,1):        if '(' == list1[m]:            flag_left = m        if ')' == list1[m]:            flag_right = m            list1[flag_left] = addormin(mulordev(list1[flag_left+1 : flag_right]))[0]            del list1[flag_left+1 : flag_right+1]            break    return list1    # return brackets(list1)str0 = '1 +2 'str4 = '10+22'str5 = '10+22-33'str6 = '10+22-33*44+55 /66 'str1 = '1+(2-3)*4/5'str2 = '10+((20-3)*4)/5'str3 = '1+(((2-3)*4)/5)'str_cal = str1# print '字符串为:%s \n计算结果为:%d\n' % (str_cal, int(addormin(mulordev(new_list(str_cal)))[0]))print brackets(new_list(str_cal))print '字符串为:%s \n计算结果为:%d\n' % (str_cal, int(addormin(mulordev(brackets(new_list(str_cal))))[0]))附:研讨会版本 和 zhengrq版本**********研讨会版本*********** #include <string.h>#define OP_ADD  '+'#define OP_SUB  '-'#define OP_EOF  '\0'typedef struct Ctx_t{    char * str;    int    pos;} Ctx;typedef struct Env_t{    Ctx ctx;    int res;} Env;typedef struct OpEnv_t{    Ctx  ctx;    char op;} OpEnv;static Env num(const Ctx ctx){    Env env;    env.res     = ctx.str[ctx.pos] - '0';    env.ctx.str = ctx.str;    env.ctx.pos = ctx.pos + 1;    return env;}static OpEnv getOp(const Ctx ctx){    OpEnv env;    env.op      = ctx.str[ctx.pos];    env.ctx.str = ctx.str;    env.ctx.pos = ctx.pos + 1;    return env;}static int addOrSub(const int left, const int right, const char op){    if (op == OP_ADD)    {        return left + right;    }    else    {        return left - right;    }}static Env calc(const Ctx ctx){    Env   env;    OpEnv opEnv;    int   res = 0;    env = num(ctx);    res = env.res;    while ((opEnv = getOp(env.ctx)).op != OP_EOF)    {        env   = num(opEnv.ctx);        res   = addOrSub(res, env.res, opEnv.op);    }    env.res = res;        return env;}int expr(const char * str){    Ctx   ctx = {(char *)str, 0};    return calc(ctx).res;}***********zhengrq版本********************
expr.h:
#include <stdio.h>
#include <ctype.h>
const int maxn = 1000;

int cal(const char *c, int i, int l);

int get(const char *c, int *i)
{
    if (c[*i] == '(')
    {
    int cnt = 1, b = *i + 1;
        for ((*i)++; cnt; (*i)++)
            if (c[*i] == '(') cnt++;
            else if (c[*i] == ')') cnt--;
        return cal(c, b, *i - 1);
    }
    int res = 0;
    for (; c[*i] && c[*i] >= '0' && c[*i] <= '9'; (*i)++) res = 10 * res + c[*i] - '0';
    return res;
}

int cal(const char *c, int i, int l)
{
    int s[maxn], top = 0, flag = 1;
    while (i < l)
    {
        if (c[i] == '+') flag = 1, i++;
        else if (c[i] == '-') flag = -1, i++;
        else if (c[i] == '*') i++, s[top] *= get(c, &i);
        else if (c[i] == '/') i++, s[top] /= get(c, &i);
        else s[++top] = get(c, &i) * flag;
    }
        int res = 0;
    while (top) res += s[top--];
    return res;
}

int expr(const char *c)
{
    int l = 0;
    while (c[l]) l++;
    return cal(c, 0, l);
}

main.cpp:

#include <stdio.h>
#include "expr.h"
#include <assert.h>


int main()
{
    char c[100];
    int x;
    while(~scanf("%d", &x))
        printf("%d\n", ~x);
    while(~scanf("%s", c)) printf("%d\n", expr(c));
    return 0;
}


原创粉丝点击