Is there an alternative to using str.substr () to extract a substring at a given position?

I am trying to compare two std :: lines and decide if line A is the same as line B but with the insertion or deletion of a single character. Otherwise, it returns false. For example: "start" and "strt" or "ad" and "add" Currently:

if(((sizeA - sizeB) != 1)
   && ((sizeB - sizeA) != 1))
{
    return false;
}

if(sizeA < sizeB)
{
    for(int i = 0; i < sizeA; ++i)
    {
        if(stringA[i] != stringB[i])
        {
            if(stringA.substr(i)
               == stringB.substr(i + 1))
            {
                return true;
            }
            else return false;
        }
    }
} //with another loop that runs only if stringA is larger than stringB

This works flawlessly, but gprof tells me that this function is bogged down. I tried converting the for loop to use iterators to access characters, but that doubled my runtime. Ive narrowed it down to using std :: string.substr (), because it builds new lines every time when stringA and stringB differ in size by 1.

, , , ?

+4
3

, , , : , , . , , , - , , :

bool oneCharDiff(std::string const& shorter, std::string const& longer) {
    if (shorter.size() + 1u != longer.size() {
        return false;
    }
    typedef std::string::const_iterator const_iterator;
    std::pair<const_iterator, const_iterator> p
        = std::mismatch(shorter.begin(), shorter.end(), longer.begin());
    return std::equal(p.first, shorter.end(), p.second + 1);
}
bool atMostOneCharDiff(std::string const& s0, std::string const& s1) {
    if (s0.size() < s1.size()) {
        return oneCharDiff(s0, s1);
    else if (s1.size() < s0.size()) {
        return oneCharDiff(s1, s0);
    }
    else {
        return s0 == s1;
    }
}
+7

Try:

if (stringA.compare(i, stringA.npos, stringB, i+1, stringB.npos) == 0) {
  /* the strings are equal */
}

, (3) std::basic_string::compare.

+3

, , ISO/IEC TS 19568: xxxx string_view.

It provides an immutable representation of a string through links without copying the string itself, so its promises will be much more efficient when working with substrings.

#include <experimental/string_view>

using std::experimental::string_view;

bool func(string_view svA, string_view svB)
{
    // ... stuff

    if(svA.size() < svB.size())
    {
        for(int i = 0; i < svA.size(); ++i)
        {
            if(svA[i] != svB[i])
            {
                if(svA.substr(i)
                   == svB.substr(i + 1))
                {
                    return true;
                }
                else return false;
            }
        }
    }

    // ... stuff
    return false;
}

As you can see, this is very similar to replacing with std::string(or const char*etc.). Just pass your regular objects std::stringas arguments to the function, and the parameters are string_viewinitialized from the passed strings.

+1
source

Source: https://habr.com/ru/post/1625755/


All Articles