计算字符串中给定电路的总电阻

Posted

技术标签:

【中文标题】计算字符串中给定电路的总电阻【英文标题】:Calculate the total resistance of a circuit given in a string 【发布时间】:2018-03-19 15:30:04 【问题描述】:

我一直在努力解决这个问题。这就是问题所在:

给定一个描述电路的字符串,计算总电阻 电路。

这是一个例子:

输入:3 5 S 预期输出:8

字符串中的操作数由运算符尾随,表示电阻是串联还是并联。然而,让我们分析一个更复杂的电路:

输入:3 5 S 0 P 3 2 S P 预期输出:0

一步一步:

    输入开头的3 5 S 为我们提供8,因此第一个中间步骤是字符串8 0 P 3 2 S P8 0 P 给了我们0,因为一个电阻短路了,因此我们得到了0 3 2 S P3 2 P5。 最后0 5 P0

这是我的尝试。我尝试使用递归,因为这似乎是一个可以通过这种方式解决的问题。首先我写了一个辅助函数:

def new_resistance(a,b,c):
if c == '':
    if int(a) == 0 or int(b) == 0:
        return 0
    else:
        return 1/(1/int(a) + 1/int(b))
else:
    return int(a) + int(b)

以及计算电路新电阻的函数:

def resistance(array):
if isinstance(array, int):
    return array
else:
    if isinstance(array,list):
        temp = array
    else:
        temp = array.split(" ")
    i = 0
    while True:
        try:
            a = new_resistance(temp[i], temp[i+1], temp[i+2])
        except Exception as e:
            i += 1            
        if len(temp[i+3:]) == 0:
            return resistance(new_resistance(temp[i], temp[i+1], temp[i+2]))
        else:
            return resistance(temp[:i] + [new_resistance(temp[i], temp[i+1], temp[i+2])] + temp[i+3:])

程序背后的想法是从列表的开头开始计算列表的前三个元素的电阻,然后将它们附加到新列表的开头(没有三个元素)并调用使用新列表再次运行。这样做直到只剩下一个整数并返回整数。

感谢任何帮助。


更新:

问题的解决方案,使用堆栈和类似于 NPR 解析器的解析器。

operator_list = set('PS')

def resistance(circuit):
  temp = circuit.split(" ")
  stack = []
  for char in temp:
      if char in operator_list:
          a = new_resistance(stack.pop(), stack.pop(), char)
          print(a)
          stack.append(a)
      else:
          print(char)
          stack.append(char)
  return stack[-1]

def new_resistance(a,b,c):
  if c == 'P':
      if float(a) == 0 or float(b) == 0:
          return 0
      else:
          return 1/(1/float(a) + 1/float(b))
  else:
      return float(a) + float(b)

circuit = '3 5 S 0 P 3 2 S P'
resistance(circuit)

# 3
# 5
# 8.0
# 0
# 0
# 3
# 2
# 5.0
# 0

【问题讨论】:

PS 前面总是正好有两个表达式吗? '0 3 5 S' 无效? @EricDuminil 因为这是一个虚拟示例,所以在提供问题的所有测试用例中都有,是的。 【参考方案1】:

问题是一旦到达0 3 2 S P,就不能简单地取前三个元素。您需要在字符串中的任何位置查找number number S_or_P

您可以为此任务使用正则表达式:

import re

circuit = '3 5 S 0 P 3 2 S P'

pattern = re.compile('(\d+) +(\d+) +([SP])')

def parallel_or_serie(m):
  a, b, sp = m.groups()
  if sp == 'S':
    return str(int(a) + int(b))
  else:
    if a == '0' or b == '0':
      return '0'
    else:
      return str(1/(1/int(a) + 1/int(b)))

while True:
  print(circuit)
  tmp = circuit
  circuit = re.sub(pattern, parallel_or_serie, circuit, count=1)
  if tmp == circuit:
    break

# 3 5 S 0 P 3 2 S P
# 8 0 P 3 2 S P
# 0 3 2 S P
# 0 5 P
# 0

注意1 1 P 将输出0.5。您可以将 int 替换为 float 并修改正则表达式以解析浮点数。

【讨论】:

【参考方案2】:

您的程序,或者更具体地说是您的parser,似乎依赖于Reverse Polish Notation,而这又是Normal Polish Notation 的一个小变体。简单地说,RPN 是一种抽象表示,其中算术表达式的运算符跟随它们的操作数,不像Normal Polish Notation 中的运算符它们的操作数。基于这种表示的解析器可以通过使用堆栈轻松实现(并且通常不需要解释括号)。

如果您的任务是开发该解析器,您可能会从我上面链接的 Wikipedia 文章中获得一些输入。

【讨论】:

我记得解决了一个与我必须转换的问题类似的问题,现在我想起来,问题非常相似。谢谢。【参考方案3】:

感谢首先识别 RPN 的 @none。

我的脑海里浮现了旧的记忆。 1980 年代,我在 8 位计算机上使用 FORTH 语言。 好的,回到 Python:

circuit = '3 5 S 0 P 3 2 S P'

stack = []
for n in circuit.split():
    if n == 'S':
        r1 = stack.pop()
        r2 = stack.pop()
        stack.append(r1+r2)
    elif n == 'P':
        r1 = stack.pop()
        r2 = stack.pop()
        stack.append(0.0 if (r1 == 0 or r2 == 0) else 1/(1/r1+1/r2))
    else:
        stack.append(float(n))

assert len(stack) == 1    
print(stack[0])

【讨论】:

【参考方案4】:

    本着 VPfB 的精神,适用于任何串并的组合(不仅是成对的)

     def calculateresistor(dataString):
     stack = []
     r = []
     cicuit=dataString
     for n in circuit.split():
         if n == 'S':
             stackSize=size(stack)
             if size(stack)>=2:
                 for k in range(0,size(stack)-1):
                     r.append(float(stack.pop()))
                     r.append(float(stack.pop()))
                     stack.append((r[-1]+r[-2]))
         elif n == 'P':
             stackSize=size(stack)
             if size(stack)>=2:
                 for k in range(0,size(stack)-1):
                     r.append(float(stack.pop()))
                     r.append(float(stack.pop()))
                     r.append(0.0 if (r[-1] == 0 or r[-2] == 0) else (1/(1/r[-1]+1/r[-2])))
                     stack.append(r[-1])
         else:
             stack.append(float(n))
     assert len(stack) == 1
     return(stack)
    

【讨论】:

以上是关于计算字符串中给定电路的总电阻的主要内容,如果未能解决你的问题,请参考以下文章

电阻电路的一般分析方法

电流电压功率的计算方式

多路三线RTD电阻温度采集电路设计方案

采样电阻是怎么进行电流采样的啊?

单片机 热敏电阻测温

如何从给定的整个 NSString 计算相同的子字符串