题目:Restore IP Addresses

将数字串转换成合法的IP地址,返回所有可能的情况。

思路:

移动3个地址分隔符".",将地址换分成四份,检查是否合法;

注意不能有0开头的地址段(它是非法的),且不用将开头的0去掉。

中间的点从第一个点的后面开始向尾部移动,当第一个点与第二个点的距离大于3时,第一个点向后移动一步,第二个点还原到当前第一个点的后面;

当第一个点移动到最后一个点的前2个位置,则,最后一个点向前移动一步,第一个点和第二个点还原;

最后一个点到串尾距离大于3则退出循环。

过程:

12301121

初始状态:1.2.30112.1

移动中间的点->1.23.0112.1->...

中间的点移动到尽头->1.230.112.1

第一个点后移一步,中间的点还原->12.3.0112.1

第一个点也移动到尽头->...->123.011.2.1

最后的点前移,前面两个点还原->1.2.3011.21->...

vector<string> LeetCode::restoreIpAddresses(string &str){
    int length = str.length();
    vector<string> strs;
    vector<int> dotPos(3);
    vector<int>::iterator firstDot = dotPos.begin();//第一个点的位置
    vector<int>::iterator lastDot = dotPos.begin();//第三个点的位置
    vector<int>::iterator middleDot = dotPos.begin();//第二个点的位置
    int dis_first_middle = 0, dis_middle_last = 0;
    middleDot++;
    advance(lastDot, 2);
    *firstDot = 1;
    *middleDot = 1;
    *lastDot = length - 1;
    do{
        (*middleDot)++;
        if (*middleDot - *firstDot > 3){//第二个地址的长度不能大于3
            (*firstDot)++;
            if (*firstDot > 3){
                *firstDot = 1;
                *middleDot = (*firstDot) + 3;
                (*lastDot)--;
            }
            if (dis_middle_last <= 3)//当第三个地址的长度小于等于3时,第二个点才回到第一个点的后一位置
                *middleDot = (*firstDot) + 1;
        }
        dis_first_middle = *middleDot - *firstDot;
        dis_middle_last = *lastDot - *middleDot;
        if (dis_first_middle < 4 && dis_middle_last < 4 && dis_first_middle > 0 && dis_middle_last > 0){
            string s1 = str.substr(0, *firstDot);
            int num = stringToInteger(s1);
            if (s1.size() > 1 && s1.at(0) == 48) continue;//去掉前面是零的情况
            if (*firstDot == 3){
                if (num > 255) continue;
            }
            string s2 = str.substr(*firstDot, dis_first_middle);
            num = stringToInteger(s2);
            if (s2.at(0) == 48 && s2.size() > 1) continue;
            if (dis_first_middle == 3){
                if (num > 255) continue;
            }
            string s3 = str.substr(*middleDot, dis_middle_last);
            num = stringToInteger(s3);
            if (s3.size() > 1 && s3.at(0) == 48) continue;
            if (dis_middle_last == 3){
                if (num > 255) continue;
            }
            string s4 = str.substr(*lastDot, length - (*lastDot));
            num = stringToInteger(s4);
            if (s4.size() > 1 && s4.at(0) == 48) continue;
            if (*lastDot + 3 <= length){
                if (num > 255) continue;
            }
            string temp(s1 + "." + s2 + "." + s3 + "." + s4);
            strs.push_back(temp);
        }
    } while (*lastDot + 3 >= length);
    return strs;
}

int LeetCode::stringToInteger(string s){
    istringstream transfer(s);//用流转换字符串成数字
    int num;
    transfer >> num;
    return num;
}