编程语言
首页 > 编程语言> > python-计算字符串中给定的电路的总电阻

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

作者:互联网

我真的一直在努力解决这个问题.这就是问题:

Given a string describing the circuit, calculate the total resistance
of the circuit.

这是一个例子:

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

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

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

一步步:

>输入开头的3 5 S给我们8,因此第一个中间步骤是字符串8 0 P 3 2 SP.
> 8 0 P给我们0,因为一个电阻器短路,因此我们得到0 3 2 SP.
> 3 2 P为5.
>,最后0 5 P为0.

这是我的尝试.我尝试使用递归,因为这似乎可以解决该问题.首先,我编写了一个辅助函数:

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

解决方法:

问题在于,一旦达到0 3 2 S P,就不能简单地采用前3个元素.无论字符串中的数字是什么,您都需要查找数字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并修改正则表达式以解析float.

标签:divide-and-conquer,python,recursion
来源: https://codeday.me/bug/20191025/1930163.html