【刷题】华为笔试题---仿LISP算法(Python实现)

最近做了一道华为的机试题,搜索之后没有找到Python实现,因此根据C++的代码实现了Python版,测试了题目描述的样例是都通过了。

1.题目描述:

  • LISP语言唯一的语法就是括号要配对。
    形如 (OP P1 P2 …),括号内元素由单个空格分割。
    其中第一个元素OP为操作符,后续元素均为其参数,参数个数取决于操作符类型
    注意:参数 P1, P2 也有可能是另外一个嵌套的 (OP P1 P2 …)
    当前OP类型为add/sub/mul/div(全小写),分别代表整数的加减乘除法。简单起见,所以OP参数个数为2

  • 举例:

输入:(mul 3 -7)输出:-21
输入:(add 1 2) 输出:3
输入:(sub (mul 2 4) (div 9 3)) 输出 :5
输入:(div 1 0) 输出:error

2.分析:

首先确定使用递归的思路来解题,然后明确递归函数的功能。设递归函数为solve_lisp(lisp_str),这个函数的功能是解析lisp样式的字符串,然后返回计算的结果(int型)。假设lisp_str的形式为'(op (sub_str1) (sub_str2)...(sub_strn))',那么solve_lisp()可以分以下5步实现:

  1. 有括号去括号;
  2. 获得操作符op,创建list用于保存后面解析的sub_str的值;
  3. 解析sub_str中的()数字
  4. 根据操作符oplist中的数字,计算最后的结果;
  5. 处理error情况、处理负号。

3.实现:

def solve_lisp(lisp_str):
    '''
    解析lisp字符串,返回一个数值
    '''
    # 去掉空格
    lisp_str = lisp_str.strip()
    
    # 去掉括号
    if lisp_str[0] == '(':
        lisp_str = lisp_str[1:]
    if lisp_str[-1] == ')':
        lisp_str = lisp_str[:-1]

    # 解析操作符
    op = lisp_str[:3]
    lisp_str = lisp_str[3:]
    
    # 保存解析出来的数值
    nums = []

    # 解析括号内的字符串
    i = 0
    while i < len(lisp_str):
        c = lisp_str[i]
        if c.isdigit() or c == '-' or c == '+':
            j = i
            while j < len(lisp_str) and (lisp_str[j].isdigit() or lisp_str[j] == '-' or lisp_str[j] == '+'): # or 需要加括号,否则越界
                j += 1
            nums.append(int(lisp_str[i:j]))
            i = j
        elif c == '(':
            j = i
            cnt = 0
            while j < len(lisp_str):
                if lisp_str[j] == '(':
                    cnt += 1
                elif lisp_str[j] == ')':
                    cnt -= 1
                j += 1
                if cnt == 0:
                    break
            nums.append(solve_lisp(lisp_str[i:j]))
            i = j
        else:
            i += 1

    # 计算数值
    # print(op, nums)
    if op == 'mul':
        cum = 1
        for num in nums:
            cum *= num
        return cum
    elif op == 'add':
        return sum(nums)
    elif op == 'div':
        return int(nums[0] / nums[1])
    elif op == 'sub':
        return nums[0] - nums[1]

def solve(lisp_str):
    try:
        print(solve_lisp(lisp_str))
    except Exception:
        print('error')

while True:
    solve(input())

4.参考资料

  1. https://blog.csdn.net/pengqianghhu/article/details/81428762
  2. https://blog.csdn.net/qq_22158743/article/details/99287194
posted @ 2022-05-07 00:02  backtosouth  阅读(398)  评论(0编辑  收藏  举报