gpt4 book ai didi

c++ - 通过仅循环一次组合 C++ 标准算法

转载 作者:可可西里 更新时间:2023-11-01 17:41:48 26 4
gpt4 key购买 nike

我目前已启动并运行此代码:

string word="test,";
string::iterator it = word.begin();
for (; it != word.end(); it++)
{
if (!isalpha(*it)) {
break;
}
else {
*it = toupper(*it);
}
}
word.erase(it, word.end());
// word should now be: TEST

我想通过以下方式使它更紧凑和可读:

  1. 组合现有的标准 C++ 算法 (*)
  2. 只执行一次循环

(*) 我假设结合现有算法可以使我的代码更具可读性......

另一种解决方案

除了按照 jrok 的建议定义自定义 transform_until 算法之外,还可以定义一个自定义迭代器适配器,该适配器将使用底层迭代器进行迭代,但通过修改返回它之前的基础引用。类似的东西:

template <typename Iterator, typename UnaryFunction = typename Iterator::value_type (*)(typename Iterator::value_type)>
class sidefx_iterator: public std::iterator<
typename std::forward_iterator_tag,
typename std::iterator_traits<Iterator>::value_type,
typename std::iterator_traits<Iterator>::difference_type,
typename std::iterator_traits<Iterator>::pointer,
typename std::iterator_traits<Iterator>::reference >
{
public:
explicit sidefx_iterator(Iterator x, UnaryFunction fx) : current_(x), fx_(fx) {}

typename Iterator::reference operator*() const { *current_ = fx_(*current_); return *current_; }
typename Iterator::pointer operator->() const { return current_.operator->(); }
Iterator& operator++() { return ++current_; }
Iterator& operator++(int) { return current_++; }
bool operator==(const sidefx_iterator<Iterator>& other) const { return current_ == other.current_; }
bool operator==(const Iterator& other) const { return current_ == other; }
bool operator!=(const sidefx_iterator<Iterator>& other) const { return current_ != other.current_; }
bool operator!=(const Iterator& other) const { return current_ != other; }
operator Iterator() const { return current_; }

private:
Iterator current_;
UnaryFunction fx_;
};

当然这仍然很原始,但它应该给出了想法。使用上述适配器,我可以编写以下内容:

word.erase(std::find_if(it, it_end, std::not1(std::ref(::isalpha))), word.end());

预先定义了以下内容(可以通过一些模板魔术来简化):

using TransformIterator = sidefx_iterator<typename std::string::iterator>;
TransformIterator it(word.begin(), reinterpret_cast<typename std::string::value_type(*)(typename std::string::value_type)>(static_cast<int(*)(int)>(std::toupper)));
TransformIterator it_end(word.end(), nullptr);

如果标准包含这样的适配器,我会使用它,因为这意味着它是完美无缺的,但由于情况并非如此,我可能会保持原样。

这样的适配器将允许重用现有算法并以今天不可能的不同方式混合它们,但它也可能有缺点,我目前可能会忽略这些缺点......

最佳答案

我不认为有一个干净的方法可以用单一的标准算法来做到这一点。据我所知,没有一个采用谓词(您需要一个谓词来决定何时提前中断)并允许修改源序列的元素。

如果你真的想以“标准”方式进行,你可以编写自己的通用算法。让我们称之为,嗯,transform_until:

#include <cctype>
#include <string>
#include <iostream>

template<typename InputIt, typename OutputIt,
typename UnaryPredicate, typename UnaryOperation>
OutputIt transform_until(InputIt first, InputIt last, OutputIt out,
UnaryPredicate p, UnaryOperation op)
{
while (first != last && !p(*first)) {
*out = op(*first);
++first;
++out;
}
return first;
}

int main()
{
std::string word = "test,";
auto it =
transform_until(word.begin(), word.end(), word.begin(),
[](char c) { return !::isalpha(static_cast<unsigned char>(c)); },
[](char c) { return ::toupper(static_cast<unsigned char>(c)); });
word.erase(it, word.end());
std::cout << word << '.';
}

这是否比您拥有的更好是值得商榷的:)有时一个简单的 for 循环是最好的。

关于c++ - 通过仅循环一次组合 C++ 标准算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14055138/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com