我想让d在这里动态化,即我希望能够在不事先知道d的值的情况下生成所有可能的数组值组合。
现在,我使用if-clause,我只能支持1到4的d。
这些是输入参数:d,max,min和sz。
if( d == 4 )
{
for( double i = min ; i <= max ; i = i+ sz )
{
for( double j = min ; j <= max ; j = j + sz )
{
for( double h = min ; h<=max ; h = h + sz )
{
for( double p = min ; p<=max ; p = p + sz )
{
double[] att = {i, j, h, p};
}
}
}
}
}
if( d == 3 )
{
for( double i = min ; i <= max ; i = i+ sz )
{
for( double j = min ; j <= max ; j = j + sz )
{
for( double h = min ; h<=max ; h = h + sz )
{
double[] att = {i, j, h};
}
}
}
}
if( d == 2 )
{
for( double i = min ; i <= max ; i = i+ sz )
{
for( double j = min ; j <= max ; j = j + sz )
{
double[] att = {i, j};
}
}
}
if( d == 1 )
{
for( double i = min ; i <= max ; i = i+ sz )
{
double[] att = {i, j};
}
}
正如你所看到的,如果我之前不知道d的价值,我就无法做到。
还有一件事,我不想使用任何模板或预定义的类,如List等。
答案 0 :(得分:1)
递归是你的朋友。对预定义类的限制使代码变得更加丑陋,但它应该完全相同。它的复杂性也非常糟糕(当你递归时,你会制作很多额外的对象),但是如果你真的想要一个可变数量的嵌套循环,这就是你想要的方法。
private static void makeAtt(double min, double max, double sz, int depth, double[] vals){
//Guard against bad depth
if (depth < 0) return;
if (depth == 0){
System.out.print("{");
for(double d : vals){
System.out.print(d + " ");
}
System.out.print("}\n\n");
}
else{
for(double i = min; i < max; i += sz){
double[] newVals = new double[vals.length + 1];
for(int z = 0; z < vals.length; z++) newVals[z] = vals[z];
newVals[vals.length] = i;
makeAtt(min, max, sz, depth - 1, newVals);
}
}
}
这是一个正在运行的示例:
public static void main(String[] args){
makeAtt(0, 3, 1, 3, new double[0]);
}
输出:
{0.0 0.0 0.0}
{0.0 0.0 1.0}
{0.0 0.0 2.0}
{0.0 1.0 0.0}
{0.0 1.0 1.0}
{0.0 1.0 2.0}
{0.0 2.0 0.0}
{0.0 2.0 1.0}
{0.0 2.0 2.0}
{1.0 0.0 0.0}
{1.0 0.0 1.0}
{1.0 0.0 2.0}
{1.0 1.0 0.0}
{1.0 1.0 1.0}
{1.0 1.0 2.0}
{1.0 2.0 0.0}
{1.0 2.0 1.0}
{1.0 2.0 2.0}
{2.0 0.0 0.0}
{2.0 0.0 1.0}
{2.0 0.0 2.0}
{2.0 1.0 0.0}
{2.0 1.0 1.0}
{2.0 1.0 2.0}
{2.0 2.0 0.0}
{2.0 2.0 1.0}
{2.0 2.0 2.0}
要注意的事情;我的代码和原始答案实际上都会生成所有可能的排列,而不是组合。如果你想要组合,你应该在递增之前使每个数字从前一个开始,而不是min。感谢递归设置的方式,您所要做的就是将递归调用更改为:
makeAtt(i, max, sz, depth - 1, newVals);
答案 1 :(得分:0)
你会爱上这个。我自己也在努力解决这个问题,经过几个小时的麻烦后设计了以下算法:
// nCr
public static long c(int n, int r) {
long result = 1;
for (int i = 1; i <= r; i++) {
result *= n - (r - i);
result /= i;
}
return result;
}
public static int[] getCombo(int n, int r, long k) {
int[] result = new int[r];
int cur = 1;
long sum = 0;
while (r > 0) {
long tot = c(n - cur, r - 1);
if (sum + tot <= k) {
sum += tot;
cur += 1;
} else {
result[result.length - r] = cur;
cur += 1;
r--;
}
}
return result;
}
public static void main(String[] args) {
for (int i = 0; i < c(10,3); i++) {
int[] res = getCombo(10, 3, i);
System.out.print(i + " : ");
for (int j : res) System.out.print(j+" ");
System.out.println();
}
}
要使用此功能,只需指定要从中选择的元素数(n)和数量(r),以及从0开始的所需组合(k)。这允许您迭代没有将它们全部保存在数组中的组合。
例如,getCombo(10,3,0)会给你[1,2,3]。当然从10中选择3有120种可能性,所以getCombo(10,3,119)会给你[8,9,10]
该算法基于计算以1和2等开头的各种数字组合。
答案 2 :(得分:0)
我的代码与@ Mshnik非常相似,但没有复制,问题是您是否可以在一个地方处理该组合,或者必须一次返回所有组合......
import java.util.*;
import java.lang.*;
import java.io.*;
class Combinations
{
static void printCombinations( int K, int[] A ) {
for ( int i = 0; i < A.length; ++i ) {
printCombinations( K, A, i, new int[K], 0 );
}
}
static void printCombinations( int K, int[] A, int from, int[] curr, int idx ) {
if ( from >= A.length ) return;
if ( idx == K ) { System.out.println( Arrays.toString(curr) ); return; }
curr[idx] = A[from];
for ( int i = from + 1; i < A.length; ++i ) {
printCombinations( K, A, i, curr, idx + 1 );
}
}
public static void main (String[] args) throws java.lang.Exception
{
BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
// K - elements in combination
int K = Integer.parseInt( br.readLine() );
// N - input array size
int N = Integer.parseInt( br.readLine() );
StringTokenizer tok = new StringTokenizer( br.readLine() );
int[] A = new int[N];
for ( int i = 0; i < N; ++i ) {
A[i] = Integer.parseInt( tok.nextToken() );
}
//System.out.println( "DEBUG: " + Arrays.toString( A ) );
printCombinations( K, A );
}
}
完整组合可用的地方
if ( idx == K ) { System.out.println( Arrays.toString(curr) ); return; }
我只是打印它,你可以把它传递给某个方法并处理它......