zoukankan      html  css  js  c++  java
  • 复原IP地址

    题目描述
    给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
    有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 '.' 分隔。
    示例

    输入: "25525511135"
    输出: ["255.255.11.135", "255.255.111.35"]

    递归方法
    需要找出所有可能复原的IP地址,因此可以考虑使用递归的方法,对所有可能的字符串分割方法进行搜索,并筛选出满足要求的作为答案
    假设题目中给出的字符串为s,使用递归函数dfs(segId,segStart)表示从s[segStart]的位置开始,搜索IP地址中的第segId段,其中segId∈{0,1,2,3,}。由于IP字段都为0-255的整数,因此从segStart开始,从小到大依次枚举当前这一段IP地址的阶数位置segEnd。如果满足要求,就递归的进行下一段搜索,调用递归函数dfs[segId+1,segEnd+1].
    特殊情况

    由于IP地址的每一段不能有前导0,如果s[segStart]等于字符0,那么IP地址的第segId段只能为0

    在递归搜索的过程中,如果已经得到了全部的4段ip地址(即segId= 4),并且遍历完了整个字符串(即segStart= |s|,其中|s|表示字符串s的长度),那么此时就是要求的答案之一,将其加入答案。在其他时刻,如果提前遍历完了字符串,需要结束遍历,回溯到上一步。

    class Solution {
    private:
        static constexpr int SEG_COUNT = 4;
    private:
        vector<string> ans;
        vector<int> segments;
    public:
        void dfs(const string &s,int segId,int segStart)
        {
            //如果找到了4段ip,并遍历完了字符串,那就是一种答案
            if(segId == SEG_COUNT)
            {
                if(segStart == s.size())
                {
                    string ipAddr;
                    for(int i = 0;i < SEG_COUNT;i++)
                    {
                        ipAddr += to_string(segments[i]);
                        if(i != SEG_COUNT-1)
                        {
                            ipAddr +=".";
                        }
                    }
                    ans.push_back(move(ipAddr));
                }
                return ;
            }
            //如果还没有找到4段ip地址就遍历完了字符串,那么提前回撤
            if(segStart == s.size())
            {
                return;
            }
            //由于不能有前导0,如果当前数字为0,那么这段IP地址只能为0
            if(s[segStart] =='0')
            {
                segments[segId] = 0;
                dfs(s,segId+1,segStart+1);
            }
            //一般情况
            int addr = 0;
            for(int segEnd = segStart;segEnd < s.size();segEnd++)
            {
                addr = addr * 10 + (s[segEnd]-'0');
                if(addr > 0 && addr <= 0xFF)
                {
                    segments[segId] = addr;
                    dfs(s,segId+1,segEnd+1);
                }
                else
                {
                    break;
                }
            }
        }
    
        vector<string> restoreIpAddresses(string s) {
            segments.resize(SEG_COUNT);
            dfs(s,0,0);
            return ans;
        }
    };
    

    知识小讲堂:
    C++ 11 std::move()

    是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝,它就是为性能而生

    c++ to_string()

    功能就是将数值转换成字符串,返回对应的字符串

    vector容器的resize()方法

    作用是改变vector容器中元素的数目

    vector容器的reserve()方法

    作用是设置容器的容量

  • 相关阅读:
    [Go] golang http下返回json数据
    [Go] Golang练习项目-邮箱imap网页版客户端工具
    [Go] 提供http服务出现两次请求以及处理favicon.ico
    [Go] 转换编码处理网页显示乱码
    [Go] go转换gbk为utf8
    [Go] golang x.(type) 用法
    [GO] go语言中结构体的三种初始化方式
    [PHP] create_function() 代码注入问题已经被弃用
    [Git] 彻底删除github上的某个文件以及他的提交历史
    [javascript] vuejs的elementui实现父子iframe通信
  • 原文地址:https://www.cnblogs.com/whiteBear/p/13461722.html
Copyright © 2011-2022 走看看