Chinaunix首页 | 论坛 | 博客
  • 博客访问: 178935
  • 博文数量: 42
  • 博客积分: 2185
  • 博客等级: 大尉
  • 技术积分: 455
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-11 21:32
文章分类

全部博文(42)

文章存档

2012年(5)

2011年(13)

2010年(6)

2009年(18)

我的朋友

分类:

2009-11-29 22:54:55

输入四个数,返回一种结果为24的算法,可用的算法为+-*/(除法只能处理整除的情况)。

使用了蛮力法,即:

输入的最多只有四个数,使用后缀表达式求值,最多三个符号,因此:

对4个数求全排列:4!种排列
对4个可能的操作符选3个,4 * 4 * 4 种可能性

对所有的这些可能性,利用后缀表达式求值。

这个是几年之前给一些学生出的C后缀表达式的时候的一个小练习,以前的C代码没了,重新整理了一个python版本的 (please don't blame my poor python):

以下是源程序(python)


#! /usr/bin/env python

class DivideError: pass
class SuffixExprError: pass

def all_perms(L):
    if len(L) <= 1:
        yield L
    else:
        for p in all_perms(L[1:]):
            for i in range(len(p) + 1):
                yield p[:i] + L[0:1] + p[i:]

def eval_two(a, b, o):
    funcs = {'+': lambda x, y: x + y,
             '-': lambda x, y: x - y,
             '*': lambda x, y: x * y,
             '/': lambda x, y: x // y,
             }
    if o == '/':
        if a % b:
            raise DivideError
    x = funcs[o](a, b)
    return x

def eval_suffix(La, Lo):
    ia = io = 0
    la = len(La)
    lo = len(Lo)
    Ta = []
    x = 0

    if la - lo != 1:
        raise SuffixExprError

    for ia in range(la):
        if len(Ta) == 1:
            o = Lo[io]
            io += 1
            x = eval_two(Ta[0], La[ia], o)
            Ta[0] = x
        else:
            Ta.append(La[ia])

    return Ta[0]

def eval_24pt(L, doall):
    operands = []
    operators = []
    ops = '+-*/'

    for o1 in ops:
        for o2 in ops:
            for o3 in ops:
                operators.append([o1,o2,o3])

    for x in all_perms(L):
        operands.append(x)

    for a in operands:
        for o in operators:
            try:
                if eval_suffix(a, o) == 24:
                    print a, o
                    if doall == 0:
                        return
            except DivideError:
                pass

def _usage():
    print 'sys.argv[0] [-a] '
    sys.exit(0)

if __name__ == '__main__':
    import sys

    L = []
    ln = len(sys.argv)
    s = 1
    doall = 0

    if ln != 5 and ln != 6:
        _usage()

    if ln == 6:
        if sys.argv[1] == '-a':
            doall = 1
        s += 1

    L = [int(sys.argv[s]), int(sys.argv[s+1]), \
                 int(sys.argv[s+2]), int(sys.argv[s+3])]

    eval_24pt(L, doall)


阅读(1396) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~