【问题标题】:Counting matches in vector of structs计算结构向量中的匹配项
【发布时间】:2013-04-02 18:21:12
【问题描述】:

我有一个问题,需要我计算此数组中使用std::count()std::find() 的实例数。我知道如何使用标准数据(参见底部代码)类型来执行此操作,但不知道我正在使用的 NameContainer

//Type
struct NameContainer{
    char name [32];
}

//An array of containers
NameContainer *_storedNames = new NameContainer[_numberOfNames];

//An example of what I'm trying to do with a string rather than the NameContainer
std::vector<string> v(_storedNames, _storedNames + _numberOfNames);
//returns an numeric value
return std::count(v.begin(), v.end(), nameToSearch))

【问题讨论】:

    标签: c++ arrays vector iterator std


    【解决方案1】:

    你可以使用仿函数

    struct names_equal {
        string comp_to;
    
        names_equal(string a) : comp_to(a) {}
    
        bool operator()(NameContainer& p) {
            return p.name == comp_to;
        }
    };
    

    然后数数

    cout << std::count_if(v.begin(), v.end(), names_equal(nameToSearch));
    

    这样nameToSearch 就不必硬编码了。


    编辑

    如果你不能使用count_if,而必须是count,那么修改NameContainer并为它重载==。

    struct NameContainer{
        string name;
    
        bool operator==(string str) {
            return name == str;
        }
    };
    

    那就这样算

    cout << std::count(v.begin(), v.end(), nameToSearch);
    

    【讨论】:

    • 我已经修好了。但我不明白为什么他可以使用count 而不是count_if
    • 非常感谢。关于显式性质,它是需要这两者之一的作业的一部分。
    • 哦,我明白了。很高兴我能帮上忙。
    【解决方案2】:

    您可以使用count_if 并提供一个谓词(一元函数,它接受范围内的元素作为参数,并返回一个可转换为布尔值的值) 例如

    bool myPred(NameContainer n){
      return (strcmp(n.name, "name") == 0); }
    
    std::vector<NameContainer> v(_storedNames, _storedNames + _numberOfNames);
    
    int i=std::count_if(v.begin(), v.end(), myPred))
    

    您可以使用strcmp() 来比较字符数组。

    如果只使用std::countstd::find

    count 和 find 都采用与容器类型相同的类型参数进行比较,在您的情况下为 NameContainerstd::count 将执行以下操作来比较搜索到的值:

    if (*first == val) 
    

    这意味着你必须重载operator==,将你的类作为参数。

    inline bool operator == (const NameContainer &first,const NameContainer &second){
            return (strcmp(first.name,second.name)==0);
        }
    

    然后拨打std::count(v.begin(), v.end(), myObjectPredicate)) myObjectPredicate 是您的 NameContainer 类对象,其名称将在向量中搜索。

    所以这是可行的解决方案。你可以在细节上改进它:

    struct NameContainer{
    char name [32];
    };
    
    inline bool operator== (const NameContainer &first,const NameContainer &second){
            return (strcmp(first.name,second.name)==0);
        }
    
    
    
    int main(int argc, char** argv) {
    
        NameContainer* _storedNames = new NameContainer[1];
        std::vector<NameContainer> vn(_storedNames, _storedNames + 1);
    
        const char* cc="piotr";
        NameContainer nc;
        memcpy(nc.name,cc,strlen(cc)+1);
        vn.push_back(nc);
    
        NameContainer myObjectPredicate;
        memcpy(myObjectPredicate.name,cc,strlen(cc)+1);
    
        int count=std::count(vn.begin(), vn.end(), myObjectPredicate);
        std::cout<<count;
    
        return 2400;
    }
    

    输出:

    1

    【讨论】:

    • 它必须是 std::count() 或 std::find()
    • 谢谢你的帮助,没想到这么简单。
    • @user2211776 查看完整示例
    【解决方案3】:

    阅读 std::count 上的文档,您会发现它使用 operator== 进行比较。因此,如果你想使用 std::count,你想比较的东西必须有一个 operator== 为它定义。在你的情况下,你可以很容易地向你的 NameContainer 添加一个。

    【讨论】:

      猜你喜欢
      • 2013-12-19
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-13
      相关资源
      最近更新 更多