Combinaciones, permutaciones y agrupaciones en java

Permutaciones
Hola que tal el día de hoy tuve algunos conflictos al intentar resolver un problema de combinaciones y bueno desempolvemos un poco nuestros libros de Probabilidad y estadística, imaginemos que tenemos 4 elementos (1,2,3,4), las combinaciones posibles entre ellos sin repetición alguna nos quedaría:
1,2,3,4,12,13,14,23,24,34,123,124,134,234,1234
15 Combinaciones en total, y si nos percatamos un poquito nos daremos cuenta que están separadas en 4 combinaciones de un solo elemento, 6 combinaciones con 2 elementos, 4 combinaciones con 3 elementos y 1 combinación con los 4 elementos, y si ya medio recordamos lo que son las combinaciones y agrupaciones, pero la bronca viene al pasarlos a java o bueno al menos a mi me dio muchísimos problemas y dolores de cabeza.
Bueno antes de pasar al código la formula para sacar el número de combinaciones posibles por cada grupo es con la formula:

n!/(n-m)!*n!

lo que podemos interpretar que será:
factorial de n(número de elementos) sobre el factorial de n por el factorial de la resta del número de elementos totales(n) menos el número de elementos por grupo.
[java]<br />
double a[]=new double[tam];//declaramos nuestro arreglo y tamaño o<br />
//tam en este caso será 4.<br />
for(int m=1;m&lt;=tam;m++){// por lo tanto haremos 4 veces<br />
double n=1;<br />
double r=1;<br />
double aux1=1;<br />
for(int i=1;i&lt;=tam;n*=i,i++);//factorial de n que será el número de elementos.<br />
int aux=(tam-m);//restamos el tamaño menos el numero de elementos en el grupo<br />
for(int i=1;i&lt;=aux;aux1*=i,i++);//factorial de aux1, que es la resta anterior<br />
for(int i=1;i&lt;=m;r*=i,i++);//factorial del número de elementos por grupo<br />
a[m-1]=n/(aux1*r);//formula para obtener número de combinaciones posibles y lo guardamos en un arreglo.<br />
}<br />
[/java]
y con esto ya tenemos las combinaciones posibles sin repetición de cada grupo; y ahora la parte un poquito complicada o al menos para mi, al momento de imprimirlos en grupo y vaya como me dio lata, pero funciona al final de cuentas, que por el momento para practica lo imprimiremos en System, pero puedes comentar esa impresión y guardar el resultado, ya sea en una cadena o en una lista o no sé en algo haz de guardarla 🙂 :
[java]<br />
int x=1;<br />
while(iter.hasNext()){//esto es por que yo tengo mis elementos en una lista y utilice un iterator para ir recorriendo toda la lista.<br />
for(int i=0;i&lt;a.length;i++){ //recorreremos el arreglo donde guardamos los valores de las combinaciones por cada grupo.<br />
for(int j=1;j&lt;=a[i];j++){//el numero de elementos a mostrar mientras no pasemos el limite<br />
for(int k=1;k&lt;=x;k++){//para imprimirlos en grupos<br />
System.out.print(iter.next());//imprimimos<br />
}System.out.println();//salto de línea y cambio de grupo<br />
}x++;<br />
}<br />
}//end while<br />
[/java]
y bueno con este código logre que nuestra entrada saliera de la siguiente manera:
1
2
3
4
12
13
14
23
24
34
123
124
134
234
1234
Quizá no sea de mucha utilidad pero espero a mi, me sirva el día de mañana jaja 🙂 y si tienen una mejor solución ojalá y puedan compartirla para ir mejorando entre todos cada día.

PD: Gracias Alex por la ayuda, no utilice tu método por que no lo pude implementar y creo lo implemente mal y no mostraba lo que necesitaba, pero poco a poco me fui dando una idea, muchas gracias compadre por la ayuda, luego nos vamos por las chelas vale?

PD2: El algoritmo que implementan está quizá mal porque no está bien su lista en este articulo solo intente expresar la forma de crear las agrupaciones de forma presentable ustedes debian de buscar el codigo para conseguir esas combinaciones; pero bien dicen: «Si vas a hacer un favor hazlo bien». Así que acá les dejo un programa sencillo y para que chequen el resultado espero les sea de gran ayuda y disculpa si no les comento el código de las combinaciones pero como no lo hice me cuesta un poco entenderlo y no recuerdo la fuente de donde lo descargue.
🙂
[java]
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.List;

public class Combinar {
static List<String> c;
List <String> d=new ArrayList<String>();
public Combinar(List<String> lis){
c=new ArrayList<String>();
sinPermutacion(lis);
d=lis;
}

public String Ar(){
String cad="";
List<String> comb=new ArrayList<String>();
Iterator iter=c.iterator();

int tam=d.size();//d=lista que nos envien
int x=1;
double a[]=new double[tam];

//fuente http://puraslineas.com/2011/01/19/combinaciones-permutaciones-y-agrupaciones-en-java/
for(int m=1;m<=tam;m++){
double n=1;
double r=1;
double aux1=1;
for(int i=1;i<=tam;n*=i,i++);//factorial de n que será el número de elementos.
int aux=(tam-m);
for(int i=1;i<=aux;aux1*=i,i++);//factorial de aux1, que es la resta anterior
for(int i=1;i<=m;r*=i,i++);//factorial del número de elementos por grupo
a[m-1]=n/(aux1*r);//formula para obtener número de combinaciones posibles y lo guardamos en un arreglo.
}

while(iter.hasNext()){
for(int i=0;i<a.length;i++){
for(int j=1;j<=a[i];j++){
for(int k=1;k<=x;k++){
cad+=(String)iter.next()+"_";//colocamos un separador
}//comb.add("\n");
cad+="\n";//colacamos un salto de linea
}
x++;
}
}
return cad;
}

public static void sinPermutacion(List lista) {
Object[] o = lista.toArray();
for (int m = 1; m <= lista.size(); m++) {
int[] posArr = new int[m];
posArr[0] = 0;
if (m > 1) {
for (int i = 1; i < m; i++) {
posArr[i] = i;
}
}
combina(posArr, m – 1, m, o);
}
}

//fuente http://puraslineas.com/2011/01/19/combinaciones-permutaciones-y-agrupaciones-en-java/
public static void combina(int[] posArr, int posCam, int dea, Object[] o) {
int cantidad = o.length;
int j;
for (j = 0; j < posArr.length; j++) {
c.add((String)o[posArr[j]]);
}
posArr[posCam]++;
if (posArr[posCam] < cantidad) {
combina(posArr, posCam, dea, o);
}
else {
int nuevaPosCam = posCam – 1;
if (nuevaPosCam >= 0) {
posArr[nuevaPosCam]++;
posArr[posCam] = posArr[posCam – 1] + 1;
if (posArr[nuevaPosCam] < cantidad – 1) {
combina(posArr, posCam, dea, o);
}
else {
boolean salida = false;
if (nuevaPosCam != 0) {
while (posArr[nuevaPosCam] >= cantidad – 1 || (salida && nuevaPosCam > 0)) {
nuevaPosCam–;
posArr[nuevaPosCam]++;
for (int i = nuevaPosCam + 1; i < dea; i++) {
posArr[i] = posArr[i – 1] + 1;
salida = posArr[i] == cantidad;
}
}
if (!salida) {
combina(posArr, posCam, dea, o);
}
}
}
}//end if nuevaPosCam>=0
}//end else
}//end combina

//fuente http://puraslineas.com/2011/01/19/combinaciones-permutaciones-y-agrupaciones-en-java/
public static void main(String ar[]){
List<String> lista=new ArrayList<String>();
lista.add("1");
lista.add("2");
lista.add("3");
lista.add("4");
Combinar comb=new Combinar(lista);
System.out.println(comb.Ar());
}
}//end class
[/java]