回答編集履歴

2 注釈追加

catsforepaw

catsforepaw score 5695

2016/05/09 00:43  投稿

10万行ともなるとコピーコストも莫迦にできませんね。文字列の途中の文字を削除しようとすると、その位置にそれ以降を文字列終端までコピーすることになり、結果、同じ部分を何度もコピーするので非効率です。
raccyさんのように別の文字列に移し替えるようにすれば最小限のコピーで済みます。
raccyさんとは別のやり方で作ってみました。文字列領域を若干多めに取ることになりますが、コピーは最小限だと思います。
※reserveで領域サイズを決め打ちしているので、もしかしたら領域の節約になっているかもしれません。  
非C++11版
```C++
struct IfCrLf
{
   bool operator ()(char ch)
   {
       return ch == '\r' || ch == '\n';
   }
};
struct IfNotCrLf
{
   bool operator ()(char ch)
   {
       return ch != '\r' && ch != '\n';
   }
};
std::string str;
str.reserve(targetStr.length());
auto iter = targetStr.begin();
while(iter != targetStr.end())
{
   auto iter2 = std::find_if(iter, targetStr.end(), IfCrLf());
   str.append(iter, iter2);
   iter = std::find_if(iter2, targetStr.end(), IfNotCrLf());
}
targetStr.swap(str);
```
C++11版
```C++
auto ifcrlf = [](char ch){return ch == '\r' || ch == '\n';};
std::string str;
str.reserve(targetStr.length());
auto iter = targetStr.cbegin();
while(iter != targetStr.cend())
{
   auto iter2 = std::find_if(iter, targetStr.cend(), ifcrlf);
   str.append(iter, iter2);
   iter = std::find_if_not(iter2, targetStr.cend(), ifcrlf);
}
targetStr.swap(str);
```
1 cbeginとcendはC++11からなので訂正

catsforepaw

catsforepaw score 5695

2016/05/09 00:35  投稿

10万行ともなるとコピーコストも莫迦にできませんね。文字列の途中の文字を削除しようとすると、その位置にそれ以降を文字列終端までコピーすることになり、結果、同じ部分を何度もコピーするので非効率です。
raccyさんのように別の文字列に移し替えるようにすれば最小限のコピーで済みます。
raccyさんとは別のやり方で作ってみました。文字列領域を若干多めに取ることになりますが、コピーは最小限だと思います。
非C++11版
```C++
struct IfCrLf
{
   bool operator ()(char ch)
   {
       return ch == '\r' || ch == '\n';
   }
};
struct IfNotCrLf
{
   bool operator ()(char ch)
   {
       return ch != '\r' && ch != '\n';
   }
};
std::string str;
str.reserve(targetStr.length());
auto iter = targetStr.cbegin();
while(iter != targetStr.cend())
auto iter = targetStr.begin();
while(iter != targetStr.end())
{
   auto iter2 = std::find_if(iter, targetStr.cend(), IfCrLf());
   auto iter2 = std::find_if(iter, targetStr.end(), IfCrLf());
   str.append(iter, iter2);
   iter = std::find_if(iter2, targetStr.cend(), IfNotCrLf());
   iter = std::find_if(iter2, targetStr.end(), IfNotCrLf());
}
targetStr.swap(str);
```
C++11版
```C++
auto ifcrlf = [](char ch){return ch == '\r' || ch == '\n';};
std::string str;
str.reserve(targetStr.length());
auto iter = targetStr.cbegin();
while(iter != targetStr.cend())
{
   auto iter2 = std::find_if(iter, targetStr.cend(), ifcrlf);
   str.append(iter, iter2);
   iter = std::find_if_not(iter2, targetStr.cend(), ifcrlf);
}
targetStr.swap(str);
```

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る