数字字符串转化成IP地址

1,441 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

##数字字符串转化成IP地址

问题描述

现在有一个只包含数字的字符串,将该字符串转化成IP地址的形式,返回所有可能的情况。

注意:ip地址是由四段数字组成的数字序列,格式如 "x.x.x.x",其中 x 的范围应当是 [0,255]。

示例:

输入:"25525522135"

输出:["255.255.22.135","255.255.221.35"]

分析问题

我们都知道IP地址是由4段数字组成的,并且用字符 “.” 进行连接。将数字字符串转换成IP地址的形式,其实就是用4个 “.” 将其分割成4个部分,并且每个部分的数字范围是[0,255]。

根据题目要求,由于要找出所有可能的IP地址,所以我们选择使用回溯算法来求解,找出所有可能的字符串分割方式,并筛选出满足IP地址要求的方式。

回溯算法都是用递归来实现的,所以我们首先来定义一下递归函数dfs(count, start),表示我们正在从s[start]的位置开始,搜索IP地址的第count段(假设给定的数字字符串是s),因为IP地址一共有4段,所以count ∈ {0,1,2,3}。对于IP地址中的每一段数字的范围是[0,255],因为我们从start的开始,从小到大的依次枚举当前一段IP地址的结束位置end。如果数字s[start,end]属于[0,255]的范围,我们就执行dfs(count+1,end+1),进行IP地址的下一段搜索。这里有一点需要注意,由于IP地址的每一段不能有前导零,即05这种是非法的,所以如果s[start]等于0,那么IP地址的这段只能为0。

在搜索的过程中,如果已经得到了全部的4段IP地址,并且已经遍历完了整个字符串,那么就代表我们已经找到了一种复原的IP地址,将其加入结果中。下面我们来看一下字符串“25525522135”的分割过程。

image-20211026140343530.png

下面我们来看一下代码的实现。

class Solution:
    def restoreIpAddresses(self, s):
        res=[]
        #Ip一共有4段组成
        ip_count = 4
        #用来存储Ip的每一段
        segments = [0] * ip_count

        def dfs(count, start):

            #如果已经找到了ip地址中的4段,并且等于字符串的长度
            #就代表找到了一种字符串的分割方式,放入结果中
            if count == ip_count:
                if start == len(s):
                    res.append(".".join(str(seg) for seg in segments))
                return

            #如果还没找完ip地址的4段就已经遍历完字符串了,表明非法,提前返回
            if start == len(s):
                return

            #由于不能有前导0,所以当s[start]=="0"时,就代表该段数字只能0
            #所以接着递归寻找下一段就好
            if s[start] == "0":
                segments[start] = 0
                #递归寻找IP地址的下一段
                dfs(count + 1, start + 1)

            #从start开始枚举
            addr=0
            for end in range(start, len(s)):
                addr = addr * 10 + (ord(s[end]) - ord("0"))
                #如果addr在[0,255]的范围,
                if 0 < addr <= 255:
                    #将这段数字加入
                    segments[count] = addr
                    #递归寻找ip地址的下一段
                    dfs(count + 1, end + 1)
                else:
                    break

        #入口,从头开始求解
        dfs(0, 0)
        return res

s=Solution()
print(s.restoreIpAddresses("25525522135"))