本博客含有两道题目:简单四则运算解析器;寻找最大葫芦
简单四则运算解析器
问题描述
小F面临一个编程挑战:实现一个基本的计算器来计算简单的字符串表达式的值。该字符串表达式有效,并可能包含数字(0-9)、运算符+、-及括号()。注意,字符串中不包含空格。除法运算应只保留整数结果。请实现一个解析器计算这些表达式的值,且不使用任何内置的eval函数。
解题思路
1、初始化两个栈:操作数栈和操作符栈
2、由于乘除运算比加减运算的运算级高,所以需要对其运算级进行定义
3、逐元素遍历输入的算式表达式:
a、如果该元素是数字,压入操作数栈
b、如果该元素是‘( ’,压入操作符栈
c、如果该元素是 + | - |* | / 且操作符栈为空或者操作符栈的最后一个字符为‘( ’或者该元素的运算级大于操作符栈的最后一个字符,则直接压入操作符栈
d、否则(与c的条件相反)如果该元素是 + | - |* | / ,先在操作符栈中弹出一个操作符,然后在操作数栈中弹出两个数字,进行相应的运算,并将计算后的数字压入操作数栈,依此逐次弹出操作符进行计算,直到满足c的条件结束循环。
e、如果该元素是‘ )’,当操作符栈不为空且或者操作符栈的最后一个字符为‘( ‘ 时,逐次弹出操作符进行循环:先在操作符栈中弹出一个操作符,然后在操作数栈中弹出两个数字,进行相应的运算,并将计算后的数字压入操作数栈,依此逐次弹出操作符进行计算,直到满足结束条件。
4、算式表达式遍历完之后,对剩余的操作符进行处理,先在操作符栈中弹出一个操作符,然后在操作数栈中弹出两个数字,进行相应的运算,并将计算后的数字压入操作数栈,依此逐次弹出操作符进行计算,直到操作符栈为空。
5、返回操作数栈的第一个数字即为答案
代码
def solution(expression):
# 初始化操作数栈和操作符栈
operand_stack = []
operator_stack = []
# 定义操作符优先级
precedence = {'+': 1, '-': 1, '*': 2, '/': 2}
# 遍历表达式
i = 0
while i < len(expression):
char = expression[i]
if char.isdigit():
# 处理数字
num = int(char)
operand_stack.append(num)
elif char in precedence:
# 处理操作符
while (operator_stack and operator_stack[-1] != '(' and
precedence[char] <= precedence[operator_stack[-1]]):
# 弹出操作符并进行计算
operator = operator_stack.pop()
b = operand_stack.pop()
a = operand_stack.pop()
if operator == '+':
operand_stack.append(a + b)
elif operator == '-':
operand_stack.append(a - b)
elif operator == '*':
operand_stack.append(a * b)
elif operator == '/':
operand_stack.append(a // b) # 整数除法
operator_stack.append(char)
elif char == '(':
# 处理左括号
operator_stack.append(char)
elif char == ')':
# 处理右括号
while operator_stack and operator_stack[-1] != '(':
operator = operator_stack.pop()
b = operand_stack.pop()
a = operand_stack.pop()
if operator == '+':
operand_stack.append(a + b)
elif operator == '-':
operand_stack.append(a - b)
elif operator == '*':
operand_stack.append(a * b)
elif operator == '/':
operand_stack.append(a // b) # 整数除法
operator_stack.pop() # 弹出左括号
i += 1
# 处理剩余操作符
while operator_stack:
operator = operator_stack.pop()
b = operand_stack.pop()
a = operand_stack.pop()
if operator == '+':
operand_stack.append(a + b)
elif operator == '-':
operand_stack.append(a - b)
elif operator == '*':
operand_stack.append(a * b)
elif operator == '/':
operand_stack.append(a // b) # 整数除法
# 返回最终结果
return operand_stack[0]
寻找最大葫芦
问题描述
在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 aa 和另外两张相同牌面值的牌 bb。如果两个人同时拥有“葫芦”,我们会优先比较牌 aa 的大小,若牌 aa 相同则再比较牌 bb 的大小。
在这个问题中,我们对“葫芦”增加了一个限制:组成“葫芦”的五张牌牌面值之和不能超过给定的最大值 max。牌面值的大小规则为:A > K > Q > J > 10 > 9 > ... > 2,其中 A 的牌面值为1,K 为13,依此类推。
给定一组牌,你需要找到符合规则的最大的“葫芦”组合,并输出其中三张相同的牌面和两张相同的牌面。如果找不到符合条件的“葫芦”,则输出 “0, 0”。
解题思路:
1、对输入进来的array数组进行牌面出现次数统计
2、针对出现次数,将出现次数大于等于3次或者2次的牌面进行记录
3、对两个记录数组进行遍历,在遍历过程中需要排除两个牌面相等的情况、五个牌面之和不大于max且’1‘的优先级大于’K‘(在遍历时给’1‘赋予最高优先级’14‘),进而在遍历过程中寻找最优值。
4、输出最优值即为结果
代码:
def solution(n, max, array):
# 统计每种牌面值的出现次数
count = {}
for card in array:
if card in count:
count[card] += 1
else:
count[card] = 1
# 生成可能的“葫芦”组合
possible_triples = [card for card in count if count[card] >= 3]
possible_pairs = [card for card in count if count[card] >= 2]
# 初始化结果
best_triple = 0
best_pair = 0
# 遍历所有可能的“葫芦”组合
for triple in possible_triples:
for pair in possible_pairs:
if triple==14:
triple=1
if pair==14:
pair=1
if triple != pair:
# 计算总和
total = 3 * triple + 2 * pair
if total <= max:
# 更新最佳组合
if triple==1:
triple=14
if pair==1:
pair=14
if triple > best_triple or (triple == best_triple and pair > best_pair):
best_triple = triple
best_pair = pair
if best_triple==14 :
best_triple=1
if best_pair==14:
best_pair=1
return [best_triple, best_pair]