3

ほとんどの場合、交換のシナリオを以下に示します。

std::string line; // "line" contains a big string.
std::string from = "abcd";
std::string to = "xy";  // to.length() < from.length()
// replace "from" with "to" everywhere in "line"

ここで、stringクラスは"xy"2文字を配置してから消去する必要があります。これにより、すべての文字が効果的lineに左にシフトされます。私のコードの存続期間中、そのような置き換えが非常に多く発生しています。

今、本当の問題になります。以下も私には受け入れられます:

// ...
if(to.legnth() < from.length())
  to.resize(from.length(), ' ');
// now to.length() = from.length()
// replace "from" with "to" everywhere in "line"

上記の演習はreplace()、同じ長さの文字列用に最適化されている場合にのみ役立ちます。それは些細なことだからです。しかし、誰かが直接の知識を持っているかどうかを確認したかっただけです。
Eclipse IDEを介して文字列クラスを参照しようとしましたが、あまり深く掘り下げることができませんでした。

4

1 に答える 1

4

MSVC2008の実装を見てみます。それら最適化します(私はいくつかのものを省略します):

_Myt& __CLR_OR_THIS_CALL replace(size_type _Off,
    size_type _N0, const _Myt& _Right, size_type _Roff, size_type _Count)
{
    ...
        if (_Count <= _N0)
        {   // hole doesn't get larger, just copy in substring
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
            _Myptr() + _Roff, _Count);  // fill hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
            _Myptr() + _Off + _N0, _Nm);    // move tail down
        }
    else if (_Roff <= _Off)
        {   // hole gets larger, substring begins before hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
            _Myptr() + _Off + _N0, _Nm);    // move tail down
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
            _Myptr() + _Roff, _Count);  // fill hole
        }
    else if (_Off + _N0 <= _Roff)
        {   // hole gets larger, substring begins after hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
            _Myptr() + _Off + _N0, _Nm);    // move tail down
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
            _Myptr() + (_Roff + _Count - _N0), _Count); // fill hole
        }
    else
        {   // hole gets larger, substring begins in hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
            _Myptr() + _Roff, _N0); // fill old hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
            _Myptr() + _Off + _N0, _Nm);    // move tail down
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _N0, _Myres - _Off - _N0, _Myptr() + _Roff + _Count,
            _Count - _N0);  // fill rest of new hole
        }
        ...
    }

新しい長さが小さい場合と長さが等しい場合は類似していることに注意してください。

編集:データをコピーした後の同じ長さの文字列の場合、合計「0」の文字/穴を移動/埋める必要があると結論付けることができます(つまり、移動しない)。したがって、最適化は実際には必要ありませんが、簡単に処理されます。

于 2013-01-14T15:49:38.217 に答える