Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何找到一个字符串是否位于另一个字符串的内部并替换它?_C++_Substr - Fatal编程技术网

C++ 如何找到一个字符串是否位于另一个字符串的内部并替换它?

C++ 如何找到一个字符串是否位于另一个字符串的内部并替换它?,c++,substr,C++,Substr,我需要以下程序的帮助。我不知道如何检查出现的string2是否在string1中,然后用string3替换它们 编写一个名为replaceSubstring的函数。函数应接受三个字符串对象参数。让我们将它们称为string1、string2和string3。它应该在string1中搜索所有出现的string2。当发现出现string2时,应将其替换为string3。用完整的程序演示和测试功能 例如,假设这三个参数具有以下值: string1:“狗跳过了栅栏” string2:“the” 第三条:

我需要以下程序的帮助。我不知道如何检查出现的
string2
是否在
string1
中,然后用
string3
替换它们

编写一个名为
replaceSubstring
的函数。函数应接受三个字符串对象参数。让我们将它们称为
string1、string2和string3
。它应该在
string1
中搜索所有出现的
string2
。当发现出现
string2
时,应将其替换为
string3
。用完整的程序演示和测试功能

例如,假设这三个参数具有以下值:

string1:“狗跳过了栅栏”

string2:“the”

第三条:“那”

使用这三个参数,函数将返回一个字符串对象,其值为“that dog over the fence”。在完整的程序中演示该功能

intmain()
{
字符串string1=“xyzxyz”;
字符串string2=“xyz”;
字符串string3=“a”;
替换子字符串(字符串1、字符串2、字符串3);
返回0;
}
void replaceSubstring(字符串string1、字符串string2、字符串string3)
{
字符串结果;
对于(int i=0;icout
string.find
返回找到的字符串的第一个字符的索引。下面是一个小示例

int main()
    {
    string myString = "ThisMessageIsPointLess";

    string strToFind = "Is";
    size_t idx = myString.find(strToFind.c_str());
    // idx = 11 because 'Is' starts at the 11th position in the string

    idx = myString.find("Foo");
    // idx == std::string::npos because it hasn't found "Foo" in myString
在所有情况下,您都应该检查是否在字符串中找到了子字符串。您只需将返回的索引与库中的默认失败值进行比较:

    if (idx == std::string::npos)
        {
        // Failed to find the substring
        return false;
        }
现在,std::string::replace有很多重载,它们可以做不同的事情。我建议您使用一个包含两个迭代器和“replacement”字符串的重载

    string replacement = "Seems";
    myString.replace(myString.begin() + idx, myString.begin() + idx + strToFind.size(), replacement.c_str());
    // myString = "ThisMessageSeemsPointless"
    return true;
我们使用的重载使用要替换的第一个字符的迭代器、要替换的最后一个字符的迭代器和替换字符串。我们知道字符串从一开始就从
idx
开始。通过简单的逻辑,我们知道它从一开始就应该在
idx+strofind.size()
结束

注:这可能与命名变量有关,以便其他人更容易理解它们。不要使用“字符串”在名称中,它的类型是“代码>字符串< /代码>,这是多余的。考虑通过代码< >令牌< /代码>和<代码> STRIG3由<代码>新令牌< /代码>或<代码>替换< /代码>……任何比数字更有意义的东西。 最后,您可能希望通过引用(对于string1)和const引用(对于string2和string3)传递变量。这将避免创建字符串的本地副本,并应提高整体性能

bool replaceSubstring(string& string1, string const& string2, string const& string3)

实现这一点的快速方法是使用前面提到的Boost String Algorithms

如果目标是实现您自己的代码来替换匹配的字符串,我建议您仔细阅读和算法。有关快速脏的解决方案,请参阅以下内容:

//用于朴素模式搜索算法的C程序
#包括
#包括
无效搜索(char*pat,char*txt)
{
int M=斯特伦(帕特);
int N=strlen(txt);
/*一个接一个滑动的循环*/

对于(inti=0;i,如果没有任何像boost这样的附加库,则需要使用std库编写一个自定义替换算法。该算法将结果字符串计算为返回值

string replaceSubstring(const string& string1, const string& string2, const string& string3)
{
    string result;
    size_t posStart = 0, posFound;
    for(; (posFound = string1.find(string2, posStart)) != string1.npos;
           posStart = posFound + string2.size())
    {
        copy(string1.begin()+posStart, string1.begin()+posFound, back_inserter(result));
        result.append(string3);
    }
    copy(string1.begin()+posStart, string1.end(), back_inserter(result));
    return result;
}
当然,您可以通过将First参数从
const string&string1
更改为
string&string1
并在返回之前根据结果分配它,轻松地将其更改为
void

如果此代码在大字符串上运行,并且如果实现没有正确优化反向插入所需的分配(注释中@RemyLebeau提出了这一问题),则可以在执行
copy
语句之前进行一些保留:

...
result.reserve(result.size() + posFound + string3.size() + 2 - posStart);
copy(string1.begin()+posStart, string1.begin() + posFound, back_inserter(result));

...
result.reserve(result.size() + string1.size() + 2 - posStart);
copy(string1.begin()+posStart, string1.end(), back_inserter(result));

您的函数有几个问题:

  • 您没有按照说明操作!“函数将返回字符串对象”。。您的函数不返回任何内容。它只是将结果输出到控制台屏幕。这应该是
    main()
    的责任

  • 您使用
    std::string::find()
    std::replace()
    的想法是正确的,但是您使用它们都是完全错误的

    • find()
      作为一个输入参数,这是无法保证的

    • 您正在调用的
      replace()
      版本需要一个起始索引和要替换的字符数。您没有将
      find()
      返回的索引传递给它,也传递了错误的字符计数

    • 您还将在输入字符串中一次循环一个字符。替换正在循环的同一输入字符串中的子字符串将对您的循环逻辑造成严重破坏

  • 话虽如此,请尝试以下方法:

    string replaceSubstring(const string &string1, const string &string2, const string &string3)
    {
        string result = string1;
        string::size_type pos = 0;
        do
        {
            pos = result.find(string2, pos);
            if (pos == string::npos) break;
            result.replace(pos, string2.length(), string3);
            pos += string3.length();
        }
        while (true);
        return result;
    }
    
    int main()
    {
        string string1 = "the dog jumped over the fence";
        string string2 = "the";
        string string3 = "that";
        string result = replaceSubstring(string1, string2, string3);
        cout << result;
        return 0;
    }
    
    字符串替换子字符串(常量字符串和字符串1、常量字符串和字符串2、常量字符串和字符串3)
    {
    字符串结果=string1;
    字符串::size\u type pos=0;
    做
    {
    pos=结果。查找(string2,pos);
    如果(pos==string::npos)中断;
    结果.更换(位置,string2.length(),string3);
    pos+=string3.length();
    }
    虽然(正确);
    返回结果;
    }
    int main()
    {
    string string1=“那条狗跳过了树
    
    // C program for Naive Pattern Searching algorithm
    #include<stdio.h>
    #include<string.h>
    
    void search(char *pat, char *txt)
    {
        int M = strlen(pat);
        int N = strlen(txt);
    
        /* A loop to slide pat[] one by one */
        for (int i = 0; i <= N - M; i++)
        {
            int j;
    
            /* For current index i, check for pattern match */
            for (j = 0; j < M; j++)
                if (txt[i+j] != pat[j])
                    break;
    
            if (j == M)  // if pat[0...M-1] = txt[i, i+1, ...i+M-1]
               printf("Pattern found at index %d \n", i);
        }
    }
    
    /* Driver program to test above function */
    int main()
    {
       char txt[] = "AABAACAADAABAAABAA";
       char pat[] = "AABA";
       search(pat, txt);
       return 0;
    }
    
    string replaceSubstring(const string& string1, const string& string2, const string& string3)
    {
        string result;
        size_t posStart = 0, posFound;
        for(; (posFound = string1.find(string2, posStart)) != string1.npos;
               posStart = posFound + string2.size())
        {
            copy(string1.begin()+posStart, string1.begin()+posFound, back_inserter(result));
            result.append(string3);
        }
        copy(string1.begin()+posStart, string1.end(), back_inserter(result));
        return result;
    }
    
    ...
    result.reserve(result.size() + posFound + string3.size() + 2 - posStart);
    copy(string1.begin()+posStart, string1.begin() + posFound, back_inserter(result));
    
    ...
    result.reserve(result.size() + string1.size() + 2 - posStart);
    copy(string1.begin()+posStart, string1.end(), back_inserter(result));
    
    string replaceSubstring(const string &string1, const string &string2, const string &string3)
    {
        string result = string1;
        string::size_type pos = 0;
        do
        {
            pos = result.find(string2, pos);
            if (pos == string::npos) break;
            result.replace(pos, string2.length(), string3);
            pos += string3.length();
        }
        while (true);
        return result;
    }
    
    int main()
    {
        string string1 = "the dog jumped over the fence";
        string string2 = "the";
        string string3 = "that";
        string result = replaceSubstring(string1, string2, string3);
        cout << result;
        return 0;
    }