简体   繁体   English

C ++-开发自己的std :: count_if版本

[英]C++ - Developing own version of std::count_if

For a task, I'm doing some simple data sampling to determine which samples contains audio counting the total number of energy. 对于一项任务,我正在做一些简单的数据采样,以确定哪些采样包含音频,该音频计数能量的总数。 I've been looking into the std::count_if function, and, although this suits my needs to a certain extent, for example: 我一直在研究std::count_if函数,尽管这在某种程度上适合我的需求,例如:

int foo = std::count_if(
               std::begin(samples), 
               std::end(samples),
               containsSound);

This counts the total number of samples that contain sound, but does not give an indication to the samples that contain sound. 这会计算包含声音的样本总数,但不会指示包含声音的样本。 I came up with this solution: 我想出了这个解决方案:

std::vector<std::string> sound_files = myLib::count_sample_if(
                                              std::begin(samples),
                                              std::end(samples),
                                              samples.DirName, 
                                              containsSOund);

This would then store and push the samples.DirName to a vector which I can then use to only store the sample set of my choice. 然后,它将存储并将samples.DirName推入vector ,然后可以使用该vector仅存储我选择的样本集。

My question is whether or not this would be easy to implement? 我的问题是这是否容易实现?

If you just need readability / speed of development and you don't care about performance then you can easily use std::copy_if and std::transform to obtain what you need: 如果您只需要可读性/开发速度,并且不关心性能,那么可以轻松地使用std::copy_ifstd::transform获得所需的内容:

std::vector<Song> songs;
std::vector<Song> filtered;
std::vector<std::string> transformed;

std::copy_if(songs.begin(), songs.end(), filtered.begin(), [](const Song &song) { return whatever you need; });
std::transform(filtered.begin(), filtered.end(), transformed.begin(), [](const Song &song) { return song.sample; });

Or you could use std::for_each : 或者您可以使用std::for_each

std::vector<Song> songs;
std::vector<std::string> transformed;

std::for_each(songs.begin(), songs.end(), [&](const Song &song) { if (song.containsSample()) transformed.push_back(song.sample); });

Then the amount of samples that contains sound is just transformed.size() . 然后,包含声音的样本数量就被transformed.size()

It would be very easy to implement - additionally, there is no need to implement it. 这将非常容易实现-另外,无需实现它。 You can write a functor (aka function object) or lambda expression to do the comparison and hold the vector for you, which would allow you to continue to use std::count_if (or one of the other standard algorithms). 您可以编写函子(又称函数对象)或lambda表达式进行比较并为您保存向量,这将使您可以继续使用std::count_if (或其他标准算法之一)。

std::vector<std::string> mySongs;
std::string myDirectory = "C:/";
std::copy_if(std::begin(samples), std::end(samples), std::back_inserter(mySongs), [](const std::string& s)
{
    // return true or false based on some criteria here
}); 
std::transform(std::begin(mySongs), std::end(mySongs), std::begin(mySongs), [](const std::string& s)
{
    return myDirectory + s;
});

If I have understood correctly the simplest way is to use standard algorithm std::copy_if. 如果我已正确理解,最简单的方法是使用标准算法std :: copy_if。 There is no need to count elements because you can simply get it by using another standard function std::distance. 不需要计数元素,因为您可以简单地通过使用另一个标准函数std :: distance来获取它。 For example let assume that you have an array of integers and want to count positive values and at the same time to copy them in a vector. 例如,假设您有一个整数数组,并且希望对正值进行计数,并同时将其复制到向量中。 The code could look the following way 该代码可能如下所示

int a[] = { 1, -3, -5, 9, 2, -4, -1, -7, 5, 8 };

std::vector<int> v;

std::copy_if( std::begin( a ), std::end( a ), 
              std::back_inserter( v ), 
              std::bind2nd( std::greater<int>(), 0 ) );

std::cout << "The number of positive elements is " << std::distance( v.begin(), v.end() ) << std::endl;

这是count_if的实现,您需要做的就是创建一个向量,如果可以接受,则推回结果,并在循环遍历整个范围后返回向量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM