C++ - Developing own version of std::count_if

若如初见. 提交于 2019-12-12 04:39:25

问题


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:

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.

My question is whether or not this would be easy to implement?


回答1:


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::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::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().




回答2:


If I have understood correctly the simplest way is to use standard algorithm std::copy_if. There is no need to count elements because you can simply get it by using another standard function 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;



回答3:


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).

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;
});



回答4:


here is the implementation of count_if, all you need to do is to create a vector, push back the result if it is acceptable, and return the vector after you finish looping through the range.



来源:https://stackoverflow.com/questions/20568278/c-developing-own-version-of-stdcount-if

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!