组合数学算法(6选2)
Algorithm for combinatorics (6 choose 2)
在此 之后,我现在想编码“6 选择 2”次“4 选择 2”。我的意思是,假设我有 6 个字符“A B C D E F”。第一次选择任意两个字符删除。第二次我想选择 2 个不同的字母进行删除,然后附加这两次试验的结果。因此,我将收到 90(“6 选 2”乘以“4 选 2”)八个字符串。模式中的字符来自相同的模式{1,2,3,4,5,6}。所有字符都是独一无二的,没有重复。
这是我目前的情况。
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;
}
我将这样调用方法:
gen8String(genDelPatterns("143256"), genDelPatterns("254316"));
目前,我正在生成所有可能的 8 字母字符串。但是我只想根据上述规范生成8个字符串。我真的很困惑如何优雅地做这个乘法。我能想到的唯一方法是制作另一种方法“4 选择 2”,然后组合 2 个字符串数组。但这似乎很迂回。
编辑: 8 个字符串的示例类似于“14322516”,考虑到我在调用 gen8String
时已经输入的输入,(143256, 254316)。请注意,前 4 个字符是从 143256 派生的,删除了 5 和 6。但是因为我在第一个路径中删除了 5 和 6,所以我不再被允许在第二个模式中删除相同的东西。因此,我从第二个模式中删除了 3 和 4。
您有一系列方法,每个方法本身都称为变体。
为此,我的建议是使用递归方法!
要实现您的目标,您必须对这个解决方案有一点经验。
利用递归的方法的简单示例:
public static long factorial(int n) {
if (n == 1) return 1;
return n * factorial(n-1);
}
我也可以建议你为方法参数传递对象(构造完美),如果传递简单变量太复杂的话
在我看来,这是该解决方案的核心。
虽然您尝试做的确实有效,但您似乎正在寻找其他方法来实现它。这是我在给定小约束的情况下会做的事情的框架。
// 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;
}
这应该会生成所有可能的 8 字符字符串。
这是我想出的解决方案。我猜并没有真正采用 "mathematical" 方法。但它完成了工作。
//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;
}
在此
这是我目前的情况。
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;
}
我将这样调用方法:
gen8String(genDelPatterns("143256"), genDelPatterns("254316"));
目前,我正在生成所有可能的 8 字母字符串。但是我只想根据上述规范生成8个字符串。我真的很困惑如何优雅地做这个乘法。我能想到的唯一方法是制作另一种方法“4 选择 2”,然后组合 2 个字符串数组。但这似乎很迂回。
编辑: 8 个字符串的示例类似于“14322516”,考虑到我在调用 gen8String
时已经输入的输入,(143256, 254316)。请注意,前 4 个字符是从 143256 派生的,删除了 5 和 6。但是因为我在第一个路径中删除了 5 和 6,所以我不再被允许在第二个模式中删除相同的东西。因此,我从第二个模式中删除了 3 和 4。
您有一系列方法,每个方法本身都称为变体。 为此,我的建议是使用递归方法! 要实现您的目标,您必须对这个解决方案有一点经验。
利用递归的方法的简单示例:
public static long factorial(int n) {
if (n == 1) return 1;
return n * factorial(n-1);
}
我也可以建议你为方法参数传递对象(构造完美),如果传递简单变量太复杂的话
在我看来,这是该解决方案的核心。
虽然您尝试做的确实有效,但您似乎正在寻找其他方法来实现它。这是我在给定小约束的情况下会做的事情的框架。
// 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;
}
这应该会生成所有可能的 8 字符字符串。
这是我想出的解决方案。我猜并没有真正采用 "mathematical" 方法。但它完成了工作。
//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;
}