用Redis来搞个计算器,边学边写redis计算功能挺有意思的
- 问答
- 2026-01-01 09:51:06
- 2
知乎用户“程序员阿明”的分享《用Redis实现一个简单计算器,边玩边学》)
好,咱们直接开干!用Redis做个计算器,听起来有点怪对吧?它明明是个存东西的数据库,咋能算数呢?别急,关键不在于让它真的去算1+1,而是用它来“计算的过程和结果,模拟出计算器的核心功能,咱们一步步来,边写边学。
第一步:先想清楚计算器要干嘛
一个最简单的计算器,起码得能做四件事:加、减、乘、除,用户按下一串按钮,3 + 5 * 2”,计算器得知道先算乘除后算加减,最后给出结果13。
但Redis自己不会算这个式子,我们的思路是:把用户输入的一长串计算表达式(3+5*2”),拆解成一个一个的小步骤,把这些步骤和中间结果都存到Redis里,然后我们写个小程序(比如用Python)去Redis里读出这些步骤,按顺序算出来。
第二步:设计怎么在Redis里“存”计算
Redis有好几种存数据的方式,这里我们用它的“列表”(List)最合适,你可以把列表想象成一个排队的队伍,数据一个接一个放进去,先放的在前面,后放的在后面,我们就把计算表达式里的数字和运算符,按顺序塞进这个列表里。
对于“3 + 5 2”: 我们就在Redis里创建一个列表,里面按顺序存上:`[“3”, “+”, “5”, “”, “2”]`。
怎么存呢?用Redis的命令,假设我们给这个计算器起个名字,它的列表叫my_calculator。
- 存数字和符号:用
LPUSH(从左边塞进去)或RPUSH(从右边塞进去),为了让顺序和我们写的顺序一样,我们用RPUSH。- 在Redis命令行里(或者在你的程序里执行Redis命令),就这样操作:
RPUSH my_calculator "3" RPUSH my_calculator "+" RPUSH my_calculator "5" RPUSH my_calculator "*" RPUSH my_calculator "2"
- 在Redis命令行里(或者在你的程序里执行Redis命令),就这样操作:
- 看看存对了没:用
LRANGE命令查看列表里所有元素。LRANGE my_calculator 0 -1应该会返回:
1) "3" 2) "+" 3) "5" 4) "*" 5) "2",完美!
第三步:写个程序来“算”
现在数据在Redis里排好队了,我们需要个“大脑”来执行计算,这里我用Python写个简单的例子,因为它读起来像伪代码,好理解。
这个“大脑”要做的事:
- 从Redis的
my_calculator列表里,把所有元素都读出来。 - 因为要考虑“先乘除后加减”,我们不能简单地从左到右算,一个常见的办法是先把表达式转换成“后缀表达式”(也叫逆波兰表达式),简单说,就是把运算符放到数字后面,像“3 + 5 2”的后缀表达式就是“3 5 2 +”,这种表达式没有括号,计算顺序是唯一的,特别适合计算机处理。
- 计算后缀表达式。
我们来写代码(来源:基于常见算法思路的简化实现):
import redis
# 连接到本地的Redis服务器
r = redis.Redis(host='localhost', port=6379, db=0)
# 1. 从Redis列表里读取计算表达式
expression_list = r.lrange('my_calculator', 0, -1)
# 读出来是字节串,我们转换成字符串
expression_parts = [item.decode('utf-8') for item in expression_list]
print("从Redis读取的表达式部分:", expression_parts)
# 2. 定义一个函数,把中缀表达式(我们平常写的)转换成后缀表达式
def infix_to_postfix(infix_tokens):
# 定义运算符的优先级
precedence = {'+': 1, '-': 1, '*': 2, '/': 2}
output = []
operator_stack = []
for token in infix_tokens:
if token.isdigit(): # 如果是数字,直接输出
output.append(token)
elif token in precedence: # 如果是运算符
# 当栈顶运算符优先级不低于当前运算符,就弹出栈顶到输出
while (operator_stack and
precedence.get(operator_stack[-1], 0) >= precedence[token]):
output.append(operator_stack.pop())
operator_stack.append(token)
# 把栈里剩下的运算符全部弹出到输出
while operator_stack:
output.append(operator_stack.pop())
return output
# 转换我们的表达式
postfix_expression = infix_to_postfix(expression_parts)
print("转换后的后缀表达式:", postfix_expression)
# 3. 计算后缀表达式
def calculate_postfix(postfix_tokens):
stack = []
for token in postfix_tokens:
if token.isdigit():
stack.append(int(token))
else:
# 弹出栈顶两个数字
b = stack.pop()
a = stack.pop()
if token == '+':
result = a + b
elif token == '-':
result = a - b
elif token == '*':
result = a * b
elif token == '/':
result = a / b
stack.append(result) # 把计算结果压回栈中
return stack[0] # 最后栈里剩下的就是最终结果
# 开始计算!
final_result = calculate_postfix(postfix_expression)
print("最终计算结果:", final_result)
# 4. (可选)把结果存回Redis,方便以后看
r.set('calculator_result', final_result)
print("结果已存回Redis,键为 'calculator_result'")
第四步:运行和扩展
你运行这个Python程序,它就会从Redis读出[“3”, “+”, “5”, “*”, “2”],转换成后缀表达式[“3”, “5”, “2”, “*”, “+”],然后计算:
- 先遇到数字3,5,2,依次压栈。
- 遇到,弹出2和5,计算5*2=10,把10压栈,现在栈里是[3, 10]。
- 遇到,弹出10和3,计算3+10=13,得到最终结果13。
看,我们就用Redis“了算式,用Python完成了计算,你可以通过修改Redis里my_calculator(用RPUSH、LPOP等命令),轻松计算不同的式子。
这有意思在哪?
- 学了Redis列表:我们用了
RPUSH存数据,LRANGE取数据,这是Redis最基础也最常用的数据结构之一。 - 理解了计算原理:为了让它能处理优先级,我们不得不去了解后缀表达式这个知识点,这是编译原理和计算器设计的核心基础之一。
- 看到了协作:Redis负责高效、持久地存储“状态”(你输入的计算式),应用程序(Python)负责复杂的逻辑运算,这是一种典型的架构思想。
你可以继续扩展这个玩具:比如加个简单的Web界面,让用户输入表达式,你把它拆解后存Redis,然后触发Python计算,最后把结果显示在网页上,这样一个完整的、有“记忆”功能的计算器就诞生了!是不是比单纯写个1+1=2的程序有意思多了?

本文由太叔访天于2026-01-01发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/72383.html
