简体   繁体   English

从字符串构建IP地址

[英]Building IP addresses from string

Write a program that determines where to add periods to a decimal string so that the resulting string is a valid IP address. 编写一个程序,该程序确定在十进制字符串的何处添加句点,以使结果字符串是有效的IP地址。 There may be more than one valid IP address corresponding to a string, in which case you should print all possibilities. 一个字符串可能有多个有效IP地址,在这种情况下,您应该打印所有可能性。 For example, "19216811" , two of the nine possible IP addresses include 192.169.1.1 and 19.216.81.1 . 例如, "19216811" ,九个可能的IP地址中的两个包括192.169.1.119.216.81.1

Below is my (incomplete) solution: 以下是我的(不完整)解决方案:

def valid_ips(string):
  def is_valid_part(part):
    return len(part) == 1 or (part[0] != 0 and int(part) <= 255)  

  def build_valid_ips(substring):
    result = []
    for i in range(1, min(4, len(substring))):
      part = substring[:i]
      if is_valid_part(part):
        for sub in build_valid_ips(substring[i:]):
          result.append(part + '.' + sub)
    return result

  return build_valid_ips(string)

This is a variant problem in the book I'm working out of, so I don't have a solution to look at. 这是我正在研究的书中的一个变体问题,因此我没有解决方案。 However, I have a couple of questions 但是,我有几个问题

  • This solution is incorrect, as it always returns an empty list but I'm not sure why. 这个解决方案是不正确的,因为它总是返回一个空列表,但是我不确定为什么。 Seems like I'm handling the inductive step and base case just fine. 似乎我正在处理归纳步骤和基本情况。 Could someone point me in the right direction? 有人可以指出我正确的方向吗?
  • How can I do this better? 我该如何做得更好? I understand each recursive call generates a new list and multiple new strings which adds a ton of overhead, but how to avoid this? 我知道每个递归调用都会生成一个新列表和多个新字符串,这会增加大量开销,但是如何避免这种情况呢?

Your function always returns an empty list because you never append anything to result in the bottom layer of recursion. 您的函数始终返回一个空列表,因为您从不添加任何内容以result递归的最底层。

In build_valid_ips you only append to result when looping through values obtained from a recursive call to build_valid_ips , but that would only return values obtained by looping through further recursive calls to build_valid_ips . build_valid_ips ,只有在遍历从对build_valid_ips的递归调用获得的值时,才追加到result ,但是那只会返回通过遍历对build_valid_ips进一步递归调用而获得的值。 Somewhere the recursion has to stop, but at this level, nothing gets appended. 递归必须在某个地方停止,但是在此级别上,什么都没有追加。 As a result there's nothing to pass back up the recursion. 结果,没有什么要传递回递归了。

Try adding the lines 尝试添加行

    if is_valid_part(substring):
        result.append(substring)

in build_valid_ips , just after the line result = [] . build_valid_ips ,在result = []result = [] You should then find that your code then returns a non-empty list. 然后,您应该找到代码,然后返回一个非空列表。

However, the result is still not correct. 但是,结果仍然不正确。 Nowhere in your code do you enforce that there must be four parts to an IP address, so the code will generate incorrect output such as 1.9.2.1.6.8.1.1 . 在代码中,没有任何地方强制要求IP地址必须包含四个部分,因此代码将生成错误的输出,例如1.9.2.1.6.8.1.1 I'll leave it up to you to modify your code to fix this. 我将由您自己来修改代码以解决此问题。

As for how to improve the code, that's more a question for Code Review . 至于如何改进代码,这是Code Review的一个问题。 For a small example such as yours, which will never run for very long, I wouldn't be too worried about generating too many lists and strings. 对于像您这样的小例子,它将永远不会运行很长时间,我不会太担心生成太多列表和字符串。 Worry about these things only when the performance of your code becomes a problem. 仅在代码性能出现问题时才担心这些事情。

Given that an IP has to contain four different parts, you can use recursion to generate a list of possibilities with groupings: 鉴于IP必须包含四个不同的部分,您可以使用递归来生成具有分组可能性的列表:

s = "19216811"
def ips(d, current = []):
  if not d:
     yield current
  else:
     for i in range(1, len(s)):
       yield from ips(d[i:], current + [d[:i]])

final_ips = list(filter(lambda x:all(len(i) > 1 for i in x[:2]), [i for i in ips(s) if len(list(filter(None, i))) == 4]))
new_ips = ['.'.join(a) for i, a in enumerate(final_ips) if a not in final_ips[:i]]

Output: 输出:

['19.21.6.811', '19.21.68.11', '19.21.681.1', '19.216.8.11', '19.216.81.1', '19.2168.1.1', '192.16.8.11', '192.16.81.1', '192.168.1.1', '1921.68.1.1']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM