简体   繁体   English

Leetcode - 去除 IP 地址

[英]Leetcode - Defanging IP address

I am doing the IP defanging challenge on Leetcode using C++.我正在使用 C++ 对 Leetcode 进行IP defanging 挑战 The following is my attempt at the solution:以下是我对解决方案的尝试:

class Solution {
public:
    string defangIPaddr(string address) {
        for(int i = 0; i < address.size(); i++){
            if(address[i] == '.'){
                address.replace(i, 1, "[.]");
            }
        }
        return address;
    }
};

Here, the code is not able to replace the period with "[.]" , it returns "Time Limit Exceeded" instead.在这里,代码不能用"[.]"替换句点,而是返回 "Time Limit Exceeded"。

I tried replacing it with "[]" and it works fine, and so does it for every other possible string combination.我尝试用"[]"替换它,它工作正常,对于所有其他可能的字符串组合也是如此。 I tried escaping, but even that doesn't work.我试过 escaping,但即使这样也行不通。

Is "[.]" some special string that cannot be read? "[.]"是一些无法读取的特殊字符串吗? I do know there is a solution where you concatenate strings iteratively, but shouldn't this work too?我知道有一个解决方案可以迭代地连接字符串,但这不应该也可以吗?

When the loop encounters the first .当循环遇到第一个. , it replaces the . , 它取代了. with [.] , thus increasing the string's size .[.] ,从而增加字符串的size But the loop is not adjusting i to account for the newly inserted [ , so the next iteration will see the same .但是循环没有调整i以考虑新插入的[ ,因此下一次迭代将看到相同的. after that new [ and perform the same replacement again, and again, and again, endlessly.在那个新的[之后,一次又一次地执行相同的替换,一次又一次,无休止。 That is why your solution is timing out.这就是您的解决方案超时的原因。

You need to make sure you are advancing i past the replacement text, eg:您需要确保将i推进到替换文本之外,例如:

class Solution {
public:
    string defangIPaddr(string address) {
        for(string::size_type i = 0; i < address.size(); ++i){
            if (address[i] == '.'){
                address.replace(i, 1, "[.]");
                i += 2; // <-- skip to ']', the subsequent ++i will then skip past it
            }
        }
        return address;
    }
};

Live Demo现场演示

Alternatively, use a while loop instead of a for loop, then you can decide more easily how much to increment i each time:或者,使用while循环而不是for循环,然后您可以更轻松地决定每次增加多少i

class Solution {
public:
    string defangIPaddr(string address) {
        string::size_type i = 0;
        while (i < address.size()){
            if (address[i] == '.'){
                address.replace(i, 1, "[.]");
                i += 3;
            }
            else {
                ++i;
            }
        }
        return address;
    }
};

Live Demo现场演示

Personally, I would use std::string::find() in the loop instead, eg:就个人而言,我会在循环中使用std::string::find() ,例如:

class Solution {
public:
    string defangIPaddr(string address) {
        string::size_type i = 0;
        while ((i = address.find('.', i)) != string::npos){
            address.replace(i, 1, "[.]");
            i += 3;
        }
        return address;
    }
};

Live Demo现场演示

Let's look at a sample input, bo.y .让我们看一个示例输入bo.y When i is 2, replace turns the string to bo[.]y .i为 2 时, replace将字符串变为bo[.]y Then, when i is 3, it sees that pesky .然后,当i为 3 时,它会看到 pesky . again, and replace turns it to bo[[.]]y .再次,并replace将其变为bo[[.]]y This keeps happening until it times out.这种情况一直发生,直到超时。

The fix?修复? increment i after you call replace:调用replace后增加i:

class Solution {
public:
    string defangIPaddr(string address) {
        for(int i = 0; i < address.size(); i++){
            if(address[i] == '.'){
                address.replace(i, 1, "[.]");
                i++;
            }
        }
        return address;
    }
};

As explained in Remy's answer , your problem lies in the fact that the loop counter never gets past the 'new' '.'正如雷米的回答中所解释的那样,您的问题在于循环计数器永远不会超过“新'.' character when you increase the string's length.增加字符串长度时的字符。

Although that answer is, in itself, faultless, I find that it is often far simpler, in any string replacement and/or substitution operation, to avoid trying to do the work 'inline';尽管该答案本身是完美的,但我发现在任何字符串替换和/或替换操作中,避免尝试“内联”工作通常要简单得多 rather, it is most often much easier to make a copy, replacing the copied parts as and when necessary:相反,制作副本通常要容易得多,必要时更换复制的部分:

class Solution {
public:
    string defangIPaddr(string address)
    {
        string answer{ "" }; // Local string to build the answer - start off empty.
        answer.reserve(address.size() * 2); // Reserve sufficient space to avoid multiple reallocation.
        for (size_t i = 0; i < address.size(); i++) {
            if (address[i] == '.') {
                answer += "[.]"; // For a dot, replace with the "[.]" string ...
            }
            else {
                answer += address[i]; // ... otherwsie, just copy the character.
            }
        }
        answer.shrink_to_fit(); // Free any unneeded memory.
        return answer; // We return BY VALUE, so a copy is made of the LOCAL "answer".
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM