zoukankan      html  css  js  c++  java
  • [LeetCode] Restore IP Address

    Given a string containing only digits, restore it by returning all possible valid IP address combinations.

    For example:
    Given "25525511135",

    return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)

    问题描述:给定一个只函数数字的字符串,得到它的所有可能的有效IP地址的组合,如上例所示。

    IP地址最小为0.0.0.0,最大为255.255.255.255。因此,它的位数限制在[4, 12]内。

    这里采用的方法有点麻烦,将[1, 1, 1, 1]到[3, 3, 3, 3]的所有组合进行测试,当然除掉0的情况,为了得到这个组合,使用了一个tri_counter类,它可以实现该功能。

    struct tri_counter{
        int val[4];
        tri_counter()
        {
            val[0] = 1;
            val[1] = 1;
            val[2] = 1;
            val[3] = 1;
        }
    
        tri_counter& operator++()
        {
            int cnt = 3;
    
            for(cnt = 3; cnt >= 0; --cnt) {
                if(val[cnt] < 3) {
                    ++val[cnt];
                    return *this;
                }
                else {
                    val[cnt] = 1;
                }
            }
            return *this;
        }
    
        bool finish()
        {
            if(val[0] != 3 || val[1] != 3 || val[2] != 3 || val[3] != 3)
                return false;
            return true;
        }
    };

    tri_counter如上所示,在构造函数中将四个整数都置1,定义前置operator++,从后面往前面遍历,当某位小于3,则加1返回,当某位等于3,则置1,继续往前遍历。定义一个finish()函数,当四个都是3时,返回真,否则返回假。它可以实现从[1, 1, 1, 1]到[3, 3, 3, 3],中间除去含0的情况。

    利用这个类得到,一个位数的组合,之后,在遍历给定的整数字符串时,可以取相应个数的字符,然后组成整数,当4个整数都在合理范围内,则得到一个有效的IP地址。

    class Solution {
    public:
        int getValue(string::iterator beg, int cnt)
        {
            int val = 0;
            int i = 0;
            while(i < cnt) {
                val = val * 10 + *beg - '0';
                ++beg;
                ++i;
            }
    
            if(val >= 0 && val <= 255) {
                if(val >= 0 && val <= 9 && cnt != 1) {
                    return -1;
                }
                if(val >= 10 && val <= 99 && cnt != 2) {
                    return -1;
                }
                if(val >= 100 && val <= 255 && cnt != 3) {
                    return -1;
                }
                return val;
            }
            else {
                return -1;
            }
        }
    
        vector<string> restoreIpAddresses(string s) {
            if(s.size() < 4 || s.size() > 12) {
                return vector<string>();
            }
    
            tri_counter tc;
            int ip_val = 0;
            bool flag = true;
            string str;
            ostringstream os(str);
            vector<string> svec;
            string::iterator iter = s.begin();
            while(!tc.finish()) {
                if(tc.val[0] + tc.val[1] + tc.val[2] + tc.val[3] != s.size()) {
                    ++tc;
                    continue;
                }
                iter = s.begin();
                flag = true;
                os.str("");
                for(int i = 0; i < 4; ++i) {
                    if((ip_val = getValue(iter, tc.val[i])) == -1) {
                        flag = false;
                        break;
                    }
                    iter += tc.val[i];
                    os << ip_val;
                    if(i != 3) {
                        os << '.';
                    }
                }
                if(flag && iter == s.end()) {
                    svec.push_back(os.str());
                }
                ++tc;
            }
            
            if(tc.val[0] + tc.val[1] + tc.val[2] + tc.val[3] == s.size()) {
                iter = s.begin();
                flag = true;
                os.str("");
                for(int i = 0; i < 4; ++i) {
                    if((ip_val = getValue(iter, tc.val[i])) == -1) {
                        flag = false;
                        break;
                    }
                    iter += tc.val[i];
                    os << ip_val;
                    if(i != 3) {
                        os << '.';
                    }
                }
                if(flag && iter == s.end()) {
                    svec.push_back(os.str());
                }
            }
    
            return svec;
        }
    };

    getValue从beg开始,将cnt个字符组成整数,如果整数是有效的,则返回整数,否则返回-1。这里要注意的是,整数的范围不仅要在[0, 255]内,最后组合成的整数的位数还要与cnt相等,比如从beg开始,获得3个字符,分别是010,但是组成的整数是10,只有两位,不满足条件。

    在restoreIpAddress中,主要是利用tri_counter中的四个整数将整数字符串进行分割,如果它是一个有效的IP地址,则加到vector中。

  • 相关阅读:
    《ASP.NET MVC 5 高级编程(第5版)》
    《JavaScript基础教程》
    Linux命令行
    jQuery UI
    第一章-算法概述
    树的基本概念及算法
    3个列表标签 uloldl
    body 部分的标签
    head 里主要的标签:meta和link 标签
    html+server+页面访问
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3469081.html
Copyright © 2011-2022 走看看