Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 密码破解程序列表子集提取的组合算法_Algorithm_Math_Passwords_Combinatorics - Fatal编程技术网

Algorithm 密码破解程序列表子集提取的组合算法

Algorithm 密码破解程序列表子集提取的组合算法,algorithm,math,passwords,combinatorics,Algorithm,Math,Passwords,Combinatorics,我一定是生疏了,因为我想不出解决办法 假设我们有3个单词列表: list1 list2 list3 ----- ----- ----- pizza red child pasta green man apple blue adult pear yellow old 我需要从每个列表中选择子集,以便: 选择的所有部分的总和将返回整个列表中所有可能的组合,例如pizza red child或pizza red man 没有重复项,所以如果选定的

我一定是生疏了,因为我想不出解决办法

假设我们有3个单词列表:

list1   list2   list3
-----   -----   -----
pizza   red     child
pasta   green   man
apple   blue    adult
pear    yellow  old
我需要从每个列表中选择子集,以便:

选择的所有部分的总和将返回整个列表中所有可能的组合,例如pizza red child或pizza red man 没有重复项,所以如果选定的第1节包含一个组合,我不希望任何其他集合包含它 所选部分需要具有一定的最小尺寸,定义为元素计数1*计数2*等 我需要有一个最小数量的选定部分 现在一个简单的解决方案当然是,假设你必须将这个列表分成4个工作人员,我称之为上面的选定部分,只需将每个组合从比萨饼发送给工作人员1,意大利面发送给工作人员2,依此类推。但如果您的工作人员多于最长列表中的元素,并且事情变得复杂,那么这是行不通的

编辑示例 因此,目标是给出一个列表,找到所有的组合。但是你需要把主要的工作分成更多的机器

上面解释的简单解决方案是,在最长的列表中有4个元素,只需使用4台机器。在这种情况下,它将如下所示:

机器1:

list1   list2   list3
-----   -----   -----
pizza   red     child
        green   man
        blue    adult
        yellow  old
list1   list2   list3
-----   -----   -----
pizza   red     child
        green   man
                adult
                old
机器2:

list1   list2   list3
-----   -----   -----
        red     child
pasta   green   man
        blue    adult
        yellow  old
list1   list2   list3
-----   -----   -----
        red     child
pasta   green   man
                adult
                old
机器3:

list1   list2   list3
-----   -----   -----
        red     child
        green   man
apple   blue    adult
        yellow  old
list1   list2   list3
-----   -----   -----
        red     child
        green   man
apple           adult
                old
机器4:

list1   list2   list3
-----   -----   -----
        red     child
        green   man
        blue    adult
pear    yellow  old
list1   list2   list3
-----   -----   -----
        red     child
        green   man
                adult
pear            old
但是,如果您必须将工作拆分到比最长列表中的元素数量更多的机器上,则这不起作用。在这种情况下,假设您需要将工作分成8台机器或每台机器两轮4台机器,它必须看起来像我使用的8,因为它使示例更简单,但实际的数字不是那么好

机器1:

list1   list2   list3
-----   -----   -----
pizza   red     child
        green   man
        blue    adult
        yellow  old
list1   list2   list3
-----   -----   -----
pizza   red     child
        green   man
                adult
                old
机器2:

list1   list2   list3
-----   -----   -----
        red     child
pasta   green   man
        blue    adult
        yellow  old
list1   list2   list3
-----   -----   -----
        red     child
pasta   green   man
                adult
                old
机器3:

list1   list2   list3
-----   -----   -----
        red     child
        green   man
apple   blue    adult
        yellow  old
list1   list2   list3
-----   -----   -----
        red     child
        green   man
apple           adult
                old
机器4:

list1   list2   list3
-----   -----   -----
        red     child
        green   man
        blue    adult
pear    yellow  old
list1   list2   list3
-----   -----   -----
        red     child
        green   man
                adult
pear            old
机器5:

list1   list2   list3
-----   -----   -----
pizza           child
                man
        blue    adult
        yellow  old
机器6:

list1   list2   list3
-----   -----   -----
                child
pasta           man
        blue    adult
        yellow  old
机器7:

list1   list2   list3
-----   -----   -----
                child
                man
apple   blue    adult
        yellow  old
机器8:

list1   list2   list3
-----   -----   -----
                child
                man
        blue    adult
pear    yellow  old

如您所见,这是一种将最大元素为4的原始列表拆分为8台机器的方法。问题是,当您无法控制列表中的计算机数量/元素数量时,如何通过编程实现这一点?

如果我没有弄错,您可以尝试替换在所选部分中选择的元素。比如,

披萨-红色-孩子

然后,

意大利面-红色-儿童

。 .

等等


因此,您不必为每个可能的组合创建新的选定部分,而是可以在完成操作后,尝试为每个可能的组合操作一个选定部分。

如果有1个工作区,则按以下顺序操作:

pizza red child
pizza red man
pizza red adult
pizza red old
pizza green child
pizza green man
pizza green adult
pizza green old
pizza blue child
pizza blue man
pizza blue adult
pizza blue old
pizza yellow child
pizza yellow man
pizza yellow adult
pizza yellow old
pasta red child
pasta red man
pasta red adult
pasta red old
pasta green child
pasta green man
pasta green adult
pasta green old
pasta blue child
pasta blue man
pasta blue adult
pasta blue old
pasta yellow child
pasta yellow man
pasta yellow adult
pasta yellow old
apple red child
apple red man
apple red adult
apple red old
apple green child
apple green man
apple green adult
apple green old
apple blue child
apple blue man
apple blue adult
apple blue old
apple yellow child
apple yellow man
apple yellow adult
apple yellow old
pear red child
pear red man
pear red adult
pear red old
pear green child
pear green man
pear green adult
pear green old
pear blue child
pear blue man
pear blue adult
pear blue old
pear yellow child
pear yellow man
pear yellow adult
pear yellow old
如果有更多工人,则按范围划分。e、 g.工人1得到披萨红孩子-披萨蓝孩子。工人2得到披萨蓝色男人-意大利面红色成人等

#include <vector>
#include <thread>
#include <cstdio>
using namespace std;

vector<vector<string>> lists = {{"apple", "pasta", "pear", "pizza"}, {"red", "green", "blue", "yellow"}, {"child", "man", "adult", "old"}};
const int K = 7;
long long N = 1;

std::vector<long long>  calc_vector(int k){
    long long remain_all = N;
    long long remain_cur = N * k / K;
    std::vector<long long>  ret;
    for(int i=0; i<lists.size(); ++i){
        long long sz = lists[i].size();
        long long i1 = remain_cur * sz / remain_all;
        ret.push_back(i1);
        remain_all /= sz;
        remain_cur -= remain_all * i1;
    }
    return ret;
}


void work(int k){
    auto v1 = calc_vector(k);
    auto v2 = calc_vector(k+1);
    while(v1 != v2){
        printf("%d: %s-%s-%s\n", k, lists[0][v1[0]].c_str(), lists[1][v1[1]].c_str(), lists[2][v1[2]].c_str());
        for(int i=v1.size()-1; i>=0; --i){
            v1[i]++;
            if(v1[i] != lists[i].size() || i==0) break;
            else v1[i] = 0;
        }
    }
}

int main(){
    for(auto &list : lists) N *= list.size();
    vector<thread> threads;
    for(int i=0; i<K; ++i) threads.push_back(thread(work, i));
    for(auto &thread : threads) thread.join();
    return 0;
}

这与普通的解决方案相同,因为替换它或选择新列表是相同的问题。在您的情况下,如果需要将工作负载拆分为4个以上的列表元素计数,该怎么办?您需要一种方法来决定如何从初始列表中选择数据,这正是我想要了解的。很抱歉,如果描述让人困惑,我也会这么想。工人一开始吃披萨,二开始吃红色,三个孩子,四个意大利面,五个绿色等等。。。我的意思是分工将取决于列而不是行。所以他们不会在同一个专栏上工作。你能给我们一个简单的答案吗?可能有助于找到解决方案,你可以强行解决。也就是说,生成一个列表中的所有组合,然后将该列表划分为与机器数量相同的多个集合考虑到你有任意多台机器,这可能是最好的解决方案,让我深思熟虑,谢谢,如果你有和组合一样多的机器,你就别无选择,只能全部生成它们,所以我认为我的解决方案是有效的,至少在大的OYes方面是有效的,但这是答案的一半。1你不能向员工发送完整的密码,否则最好自己测试。2如果你将此应用于6列中的前3列,比如说,你可能会在最后3列/列表中出现大量组合,这是行不通的。因此,您需要一种更平均地拆分它们的方法,要求每个工作人员的最大列/列表大小,这就是我所要求的。很抱歉,我第一次无法更好地描述它,我也很抱歉,似乎没有一个简单的解决方案。这很有效。我觉得我很好,这对我来说就像是外星人的密码。非常感谢。