3

substr メンバー関数を正しく理解しているかどうか教えてください。
result = result.substr(0, pos) + result.substr(pos + 1);
pos から 0 までの文字列を取得し (ただし、含まれません)、 残りの文字列を連結しremove[i]
ます。+ result.substr(pos + 1);remove

string removeLetters2(string text, string remove)
{
    int pos;
    string result = text;

    for (int i = 0; i < remove.length(); i++)
    {
        while (true)
        {
            pos = result.find(remove[i]);                
            if (pos == string::npos)                      
            {
                break;
            }
            else
            {
                result = result.substr(0, pos) +
                result.substr(pos + 1);
            }
        }
    }
    return result;
}
4

4 に答える 4

7

要するに、あなたは尋ねていますか

result = result.substr(0, pos) +
         result.substr(pos + 1);

位置の文字を削除しposますよね?

簡潔な答え:

はい。

より長い答え:

引数が 2 つの呼び出しは、開始インデックス長さを取ります(引数が 1 つの呼び出しは、文字列の末尾に移動します)。

次のような文字列を想像するのに役立ちます。

F o o / B a r
0 1 2 3 4 5 6   <- indices

今すぐ削除/

F o o / B a r
0 1 2 3 4 5 6   <- indices
1 2 3 |         <- 1st length
      | 1 2 3   <- 2nd length

result = result.substr(0, 3)   <- from index 0 with length 3
       + result.substr(4);     <- from index 4 to end

プログラマーとして、距離/インデックスと長さの違いに常に注意してください。

ベター: インデックスがわかっている場合:

コードは 2 つの新しい一時文字列を作成し、それらを連結して 3 番目の一時文字列にし、それを にコピーしresultます。

stringその場で消去(ウィンクウィンク)するように依頼することをお勧めします。

result.erase(pos,1);
// or by iterator
string::iterator it = ....;
result.erase(it,it+1);

これにより、実装者は最適化の自由度が高まり、string実装者は pos の後のすべての文字を 1 つ左に移動することを選択できます。これは、特殊なシナリオでは、単一の割り当て、単一のループ、およびループ内で x86 スワップ命令を使用して実装できます。

ベター: 削除する文字がわかっている場合:

または、これによりパフォーマンスが向上するかどうかはわかりませんが、より良いコード、アルゴリズムが得られる可能性があります。remove_if

#include <algorithm>

// this would remove all slashes, question marks and dots
....
    std::string foobar = "ab/d?...";
    std::remove_if (foobar.begin(), foobar.end(), [](char c) {
        return c=='/' || c=='?' || '.';
    });

remove_if任意の関数オブジェクトを受け入れます。

文字が 1 つしかない場合は、次のように簡単になります。

// this would remove all slashes
std::remove (foobar.begin(), foobar.end(), '/');
于 2012-11-07T14:21:15.403 に答える
4

あなたの質問に対する答えは「はい」ですが、あなたがやろうとしていることについてもっと良い方法があります。string::erase次のように使用します。

result.erase(pos, 1);

この API は、文字列から文字を削除するために設計されています。同じ結果をはるかに効率的に達成します。

于 2012-11-07T14:23:06.753 に答える
0

dasblinkenligntの応答は良いものですが、複数のタイプの文字を削除するように見えるのでremove_if、特別な述語も見てください。<algorithm>

于 2012-11-07T14:29:18.237 に答える
0

はい、この関数はremoveからのすべての文字を削除しtextます。

于 2012-11-07T14:24:56.763 に答える