使用字符串生成IP地址

时间:2016-09-26 19:18:54

标签: c++ recursion

我一直在学习递归,我确实得到了关于它们如何工作以及如何编码它们的概念。现在,正常的递归很容易可视化,但是当递归涉及循环时,它们完全令人费解。

让我们首先回答这个问题,假设,我有一个字符串,我必须找到可以使用该字符串生成的有效IP地址。

实施例

11211

可能的IP地址

1.1.2.11
1.1.21.1
1.12.1.1
11.2.1.1

我试图用给定代码

之类的东西来实现这一点
vector<string> v;
string period(string str,int i){
    size_t pos=str.find_last_of(".");
    if(pos==string::npos)
        str.insert(i+1,".");
    else
        str.insert(pos+2,".");
    v.push_back(str);
    return str;
}

void recursion(string str){
    for(int i=0;i<=2;i++)
        {
            cout<<i<<'\n';
            string strx=period(str,i);
            if(count(strx.begin(),strx.end(),'.')<4)
                recursion(str);
        }
}
bool validIPaddress(string str){
    //return true for valid ip address
}
int main () {
    string str("11211");
    recursion(str);
    for(vector<string>::iterator it=v.begin();it!=v.end();++it){
    if(validIPaddress(*it))
        cout<<*it<<'\n';
  }
}

enter image description here

我已经为我的逻辑制作了一张照片。

尝试我可以将.置于字符串之间的每个可能的位置,并将每个可能的组合保留在已全局声明的向量中,并且不要在字符串中放置超过3个句点。< / p>

递归完成后,我使用句点进行所有可能的组合,我可以循环遍历该向量并找到有效的。

现在,问题在于,当我尝试实现这个逻辑时,我的输出并不像我预期的那样。我试着调试我的代码并看一眼我做错了但是我无处可去

如何使用递归实现上述问题的解决方案?

此致

BOTJr。

2 个答案:

答案 0 :(得分:2)

你的想法很完美,你不应该使用循环。通常我们在处理递归函数时不使用循环。实际上,这个问题不涉及循环,你只需要两次调用递归函数。

你的问题是每个循环都会再次调用你的函数,这意味着再多三次迭代。每次迭代将再次意味着三次迭代,这将被无限调用。此外,您保存向量中的每个字符串,但它足以保存正确的字符串。由于我们需要知道下一个句点的位置,我们将在递归函数中添加一个新的位置参数。

首先,我们必须将期间添加到预期的位置。

void recursion(const string& str, const size_t i = 1){
    //Create a copy of the constant string
    string strx = str;
    //The insert method will insert one dot before the
    //i positioned character in the string
    strx.insert(i, 1, '.');

    //...

在插入这一段时间之后,我们只需要回忆一下这个功能,但是只有在有新时期的地方,或者我们没有3个需要的时期。

    //...
    if(count(strx.begin(), strx.end(), '.') < 3)
    {
        //If the count of periods in the new string is under three,
        //then we need to add a new period.
        if (i < strx.size() - 2) recursion(strx, i + 2);
    }
    else
    {
        //The else means, the number of periods if greater or equal
        //to 3. Actually, the only possibility is the equality, so
        //we can add the string to the vector
        v.push_back(strx);
    }

    //Also, we call the recursion on the unmodified string, which means
    //we will get IP numbers starting with two numbers too.
    if (i < str.size() - 1) recursion(str, i + 1); //recall on original
}

这样,您不必在最后调用检查功能。请注意,我们会在第一次调用时检查长度(或大小) - 2,因为我们不希望获得1..12.11

答案 1 :(得分:1)

我根据我的问题做了一些改变。我使用了地图,但也可以使用矢量。

此外,ValidIPaddress函数考虑对IP地址的基本检查,但是它不会检查诸如位于0-255范围内的八进制的检查。

map<string,string> v;
bool validIPaddress(string);
string period(string str,int i){
size_t pos=str.find_last_of(".");
if(pos==string::npos)
    str.insert(i+1,".");
else
    if(pos+i+2<=str.length())
         str.insert(pos+i+2,".");
    else return "terminate";

    if(validIPaddress(str))
         v[str]=str;
    return str;
}

void recursion(string str){
        if(str!="terminate")
        {
            if(count(str.begin(),str.end(),'.')<3)
            {
              string other=str;
              for(int i=0;i<=2;i++)
                {
                    recursion(period(str,i));
                    str=other;
                }

            }

        }

}
bool validIPaddress(string str){
 int periods_used=count(str.begin(),str.end(),'.');
   if(periods_used!=3)
        return false;

   size_t pos=str.find_last_of('.');
   if(str.substr(pos+1).length()<1)
     return false;

   int i=0;
   while(i<3)
   {
       int found=str.find('.');
       string strx=str.substr(0,found);
       if(strx.length()<1 || strx.length()>3)
          return false;
       str=str.substr(found+1);
       i++;
   }
    return true;
}
int main () {
string str("11211");
if(str.length()>=4)
   recursion(str);
else
{
    cout<<"No possible IP addresses can be generated."<<'\n';
    exit(1);
}
for(map<string,string>::iterator it=v.begin();it!=v.end();++it)
     cout<<it->first<<'\n';
}

输出:

1.1.2.11
1.1.21.1
1.12.1.1
11.2.1.1