生成一组所有组合

Posted

技术标签:

【中文标题】生成一组所有组合【英文标题】:Generating a set of all combinations 【发布时间】:2021-07-27 17:49:14 【问题描述】:

我正在尝试解决a problem:

有一个由 n 个问题组成的调查,每个问题的答案是 0(否)或 1(是)。学生的答案由 2D 整数数组 students 表示,其中 students[i] 是一个整数数组,其中包含第 i 个学生(0 索引)的答案(对于导师也是如此)。 每个学生将被分配给一名导师,每个导师将分配给他们一名学生。 学生-导师对的兼容性分数是学生和导师的相同答案的数量。 例如:如果students = [[1,1,0],[1,0,1],[0,0,1]]mentors = [[1,0,0],[0,0,1],[1,1,0]] 则输出应为8。 (学生 0 与导师 2 配对(得分 3),学生 1 与导师 0 配对(得分 2),学生 2 与导师 1 配对(得分 3)。总兼容性:8

约束很小,所以我使用暴力生成所有学生组合的方法,来计算最大兼容性分数:

class Solution 
public:
    int check(vector<int>& s, vector<int>& m) 
        // calculates and returns max compatibility score
        int res=0;
        
        for(int i=0; i<s.size(); i++)
            if(s[i]==m[i]) res++;
        
        return res;
    

    int maxCompatibilitySum(vector<vector<int>>& students, vector<vector<int>>& mentors) 
        int res=0;
        
        sort(students.begin(), students.end());
        do 
            int curr=0;
            // for(auto s: students) 
            //     for(auto val: s) 
            //         cout<<val<<" ";
            //     
            //     cout<<"\n";
            // 

            for(auto s: students) 
                for(auto m: mentors) 
                    curr+=check(s, m);
                
            
            res=max(res, curr);
         while(next_permutation(students.begin(), students.end()));
        
        return res;
    
;

注释代码确实显示了正确生成的不同组合。但我得到的输出是14 而不是8。我做错了什么?

【问题讨论】:

为什么要使用外循环?无论排列如何,两个内部 for 循环都会产生相同的结果 您实际上是在计算同时将所有学生分配给所有导师的兼容性分数。您应该在循环的每次迭代中线性地向 curr 添加很多东西,而不是二次方。 @NathanPierson,并没有完全跟进。能详细点吗? @Someone 已经发布了一个答案,其中包括我所说的内容,并提出了修复建议。 【参考方案1】:

我猜你想在每个排列中将每个学生与不同的导师配对。但这不是你在这里做的:

        for(auto s: students) 
            for(auto m: mentors) 
                curr+=check(s, m);
            
        

这两个循环计算与所有导师配对的所有学生的总和。在外循环的每次迭代中,这两个 for 循环产生相同的结果,因为students 的顺序无关紧要。

我想你想要的是这个:

  for (size_t i = 0; i < std::min(students.size(),mentors.size()); ++i) 
       curr += check( students[i], mentor[i]);
  

这会将第 i 个学生与第 i 个导师配对。在do 循环的下一次迭代中,会有不同的配对。

【讨论】:

哦,我现在明白了。由于这两个循环,我生成了所有学生-导师对,而不是真正将ith 学生与ith 导师配对!谢谢!

以上是关于生成一组所有组合的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 LINQ 从一组数字中查找 n 项的所有组合?

最大数量组合

PHP算法从单个集合中生成特定大小的所有组合

过滤字母组合

用一组字符替换字符串中的“#”,给出所有可能的字符串组合[关闭]

Excel VBA中的组合算法