字符串::查找问题 (C++)

string::find Issue (C++)

本文关键字:C++ 问题 查找 字符串      更新时间:2023-10-16

我的字符串::find实现有一点问题。

输入是一个长字符串,由以下可能的示例组成:input = "one_thousand_and_fifty_one"。

我的问题似乎是,在包含多个"和"的输入字符串中,只有第一个被删除,而其他的则不被删除。

这是我到目前为止的代码,它找到"和",但只有在"a"之前的字母不是"s"(表示"千")时才删除。

string toKill = "and";
size_t andF = input.find(toKill);
    if (andF != string::npos) {
        if (input[(andF - 1)] != 's') {
            input.erase(andF, 4);
        }
    }

编辑:我忘了提到,输入中唯一包含"and"的另一个单词是"千",所以这是一个特例。

试试这个:

string toKill = "and";
size_t andF = 0;
while ((andF = input.find(toKill, andF)) != string::npos) {
    if (andF == 0 || input[andF - 1] != 's') {
        input.erase(andF, 4);
    }
    else ++andF;
}

我会为此使用正则表达式(来自 boost、PCRE 或 C++11 标准) - 但如果必须我自己做,我的代码会看起来像这样:

string toKill = "and";
size_t pos = 0;
while( ( pos = s.find(toKill, pos) )!=std::string::n_pos )
{
  //Check it doesn't start with an additional letter
  if( pos!=0 && is_alpha(s[pos-1]) ) { pos++; continue; }
  //Check it doesn't end with an additional letter
  if( pos+toKill.size()!=s.size() && is_alpha(s[pos+toKill.size()]) { pos++; continue;}
  //Remove it and the trailing whitespace (or punctuation)
  s.erase(pos,toKill.size()+1);
}

代码中(至少)需要另外两件事。第一个是处理and字符串的整个字符串的循环,第二个是跳过已检查字符串的能力。

您可能还希望处理字符串可能and 开头的可能性,尽管这不太可能:对你的期望要自由,对你交付的东西要具体

以下代码将是一个很好的起点:

#include <iostream>
#include <string>
int main (void) {
    std::string inputStr = "one thousand and fifty one";
    std::string killStr = "and ";
    size_t startPos = 0;
    size_t andPos;
    while ((andPos = inputStr.find (killStr, startPos)) != std::string::npos) {
        if ((andPos == 0) || (inputStr[(andPos - 1)] != 's')) {
            inputStr.erase(andPos, killStr.length());
            startPos = andPos;
        } else {
            startPos = andPos + 1;
        }
    }
    std::cout << inputStr << 'n';
    return 0;
}

而且,由于我对在字符串的开头使用 and 很偏执,并且 Michael 正确地要求我不在字符串 (a)的末尾处理它,你可以修改它,这样做如下:

#include <iostream>
#include <string>
#include <cstring>
static bool endsWith (std::string s1, std::string s2) {
    size_t s1Len = s1.length();
    size_t s2Len = s2.length();
    if (s2Len > s1Len)
        return false;
    return (strcmp (s1.c_str() + s1Len - s2Len, s2.c_str()) == 0);
}
int main (void) {
    std::string inputStr = "and one thousand and fifty one thousand and";
    std::string killStr = "and ";
    size_t startPos = 0;
    size_t andPos;
    while ((andPos = inputStr.find (killStr, startPos)) != std::string::npos) {
        if ((andPos == 0) || (inputStr[(andPos - 1)] != 's')) {
            inputStr.erase (andPos, killStr.length());
            startPos = andPos;
        } else {
            startPos = andPos + 1;
        }
    }
    if (!endsWith (inputStr, "sand") && endsWith (inputStr, "and"))
        inputStr.erase (inputStr.length() - 3);
    std::cout << inputStr << 'n';
    return 0;
}

(a)如果我要成为一个学究,我最好做得好:-)