#c #c 11
#c #c 11
Вопрос:
Как использовать copy_if
фильтр str
конкретного кратного индекса.
например str
, это «1000020000300004000050000», я хочу newStr
, чтобы это было «12345».
В соответствии с 1 равно 5 * 0, 2 равно 5 * 1, 3 равно 5 * 2 и т.д.
Исходный код :
std::string str("1000020000300004000050000");
std::string newStr;
std::copy_if(str.begin(), str.end(),
std::back_inserter(newStr),
[] (char c) {
// Some specific rule I want to return.
return ...;
}
);
Идеальный код :
std::copy_if(str.begin(), str.end(),
std::back_inserter(newStr),
[] (char c) {
// I can get the index of iteration.
return (index % 5 == 0);
}
);
Комментарии:
1. Что не так с простым циклом for?
2. Я хочу знать, можно ли сделать то же самое
copy_if
или нет. Спасибо за ваш комментарий.![]()
Ответ №1:
Вы можете передать начало строки и текущий итератор в качестве захвата лямбда-функции и использовать их соответствующим образом (тогда лямбда-выражение должно быть изменяемым):
std::string str("1000020000300004000050000");
std::string newStr;
std::copy_if(str.begin(), str.end(),
std::back_inserter(newStr),
[it = str.begin(), beg = str.begin()] (auto c) mutable {
// I can get the index of iteration.
return (std::distance(it , beg) % 5 == 0);
}
Комментарии:
1. Это интересный способ сделать это. Просто обратите внимание, что для неслучайного accessiterator
std::distance
имеет линейную сложность (не проблема для данного конкретного случая). Также для общего лямбда-выражения требуется C 14
Ответ №2:
Вы можете отслеживать индекс в локальной переменной. Обратите внимание, что вам нужно захватить i
по ссылке. т.е. [amp;i]
int i = 0;
std::copy_if(str.begin(), str.end(),
std::back_inserter(newStr),
[amp;i] (char c) {
int index = i ;
return (index % 5 == 0);
}
);