简体   繁体   English

组合算法(6选2)

[英]Algorithm for combinatorics (6 choose 2)

Following this question , I want to now code "6 choose 2" times "4 choose 2." 在这个问题之后 ,我想现在编码“6选2”次“4选2”。 By that I mean, lets say I have 6 characters "ABCDE F." 我的意思是,我可以说我有6个字符“ABCDE F.” The first time I choose any two characters to delete. 我第一次选择任意两个字符来删除。 The 2nd time I want to choose 2 different letters to delete and then I append the results of these two trials. 第二次我想选择2个不同的字母来删除,然后我追加这两个试验的结果。 Hence, I will receive 90("6 choose 2" times "4 choose 2") eight character strings. 因此,我将收到90个(“6选2”次“4选2”)八个字符串。 The characters in the pattern are from the same pattern {1,2,3,4,5, 6}. 模式中的字符来自相同的模式{1,2,3,4,5,6}。 All the characters are unique and no repetition. 所有角色都是独一无二的,没有重复。

Here is what I have so far. 这是我到目前为止所拥有的。

public String[] genDelPatterns(String design){
    char[] data = design.toCharArray();
    String[] deletionPatterns = new String[15];
    int x = 0;
    StringBuilder sb = new StringBuilder("");
    int index = 0;
    for(int i = 0; i < (6-1); i++){
        for(int j = i+1; j < 6; j++){
            for(int k= 0; k < 6; k++){
                if((k != j) && (k != i))
                    sb.append(String.valueOf(data[k]));
            }
            deletionPatterns[x++] = sb.toString();
            sb = new StringBuilder("");
        }
    }
    return deletionPatterns;
}
public String[] gen8String(String[] pattern1, String[] pattern2){
    String[] combinedPatterns = new String[225];
    int k = 0;
    for(int i = 0; i < 15; i++)
    {
        for(int j = 0; j < 15; j++)
            combinedPatterns[k++] = pattern1[i] + pattern2[j];
    }
    return combinedPatterns;
}

I will be calling the methods like this: 我将调用这样的方法:

gen8String(genDelPatterns("143256"), genDelPatterns("254316"));

Currently, I am generating all the possible 8 letter strings. 目前,我正在生成所有可能的8个字母字符串。 But I want to only generate the 8 character strings according to the aforementioned specifications. 但是我想根据上述规范只生成8个字符串。 I am really stuck on how I can elegantly do this multiplication. 我真的很困惑,我怎么能优雅地做这个乘法。 The only way I can think of is to make another method that does "4 choose 2" and then combine the 2 string arrays. 我能想到的唯一方法是制作另一种方法,即“4选2”,然后组合2个字符串数组。 But this seems very roundabout. 但这似乎非常迂回。

EDIT: An example of an 8 character string would be something like "14322516", given the inputs I have already entered when calling gen8String , (143256,254316). 编辑:一个8字符串的例子就像“14322516”,给定我在调用gen8String时输入的输入,(143256,254316)。 Note that the first 4 characters are derived from 143256 with the 5 and 6 deleted. 请注意,前4个字符来自143256,删除了5和6。 But since I deleted 5 and 6 in the first trail, I am no longer allowed to delete the same things in the 2nd pattern. 但是因为我在第一个路径中删除了5和6,所以我不再允许在第二个模式中删除相同的东西。 Hence, I deleted the 3 and 4 from the 2nd pattern. 因此,我从第2个模式中删除了3和4。

you have a chain of methods , each one called a variation itself. 你有一系列方法,每个方法都称为变异。 For so, my advice is to use a recursive method! 为此,我的建议是使用递归方法! to achieve your goal you have to have a little experience with this solution. 要实现您的目标,您必须对此解决方案有一点经验。

A simple example of a method that exploits the recursion: 利用递归的方法的一个简单示例:

public static long factorial(int n) { 
    if (n == 1) return 1; 
    return n * factorial(n-1); 
} 

I can also suggest you to pass objects (constructed to perfection) for the method parameter, if is too complex to pass simple variables 我还建议您为方法参数传递对象(构造为完美),如果太复杂而无法传递简单变量

This is the heart of this solution in my opinion. 在我看来,这是这个解决方案的核心。

While what you tried to do is definitely working, it seems you are looking for other way to implement it. 虽然你试图做的肯定是有效的,但似乎你正在寻找其他方法来实现它。 Here is the skeleton of what I would do given the small constrains. 这是我给出小约束时会做的骨架。

// Very pseudo code
// FOR(x,y,z) := for(int x=y; x<z;x++)

string removeCharacter(string s, int banA, int banB){
     string ret = "";
     FOR(i,1,7){
         if(i != banA && i != banB){
              ret += s[i];
         }
     }
    return ret;
}

List<string> Generate(s1,s2){
    List<string> ret = new List<string>();
    FOR(i,1,7) FOR(j,i+1,7) FOR(m,1,7) FOR(n,m+1,7){
         if(m != i && m != j && n != i && n != j){
             string firstHalf  = removeCharacter(s1,i,j);
             string secondHalf = removeCharacter(s2,m,n);
             ret.Add(firstHalf + secondHalf);
         }
    }
    return ret;
}

This should generate all possible 8-characters string. 这应该生成所有可能的8个字符的字符串。

Here is the solution I came up with. 这是我提出的解决方案。 Doesn't really take "mathematical" approach, I guess. 我猜不是真的采用“数学”方法。 But it does the job. 但它完成了这项工作。

//generating a subset of 90 eight character strings (unique deletion patterns)
    public static String[] gen8String(String[] pattern1, String[] pattern2){
        String[] combinedSubset = new String[90]; //emty array for the subset of 90 strings
        String  combinedString = ""; //string holder for each combined string
        int index = 0; //used for combinedSubset array
        int present = 0; //used to check if all 6 characters are present

        for(int i = 0; i < 15; i++){

            for(int j = 0; j < 15; j++){
                combinedString = pattern1[i] + pattern2[j]; //combine both 4 letter strings into 8 char length string
                char[] parsedString = combinedString.toCharArray(); //parse into array

                //check if all 6 characters are present
                for(int k = 1; k <= 6; k++)
                {
                    if(new String(parsedString).contains(k+"")) {
                        present++;
                    }
                    else
                        break;
                    //if all 6 are present, then add it to combined subset
                    if(present == 6)
                        combinedSubset[index++] = combinedString;
                }
                present = 0;
            }
        }
        return combinedSubset;
    }

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

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