Permutations d'éléments de matrice
Fermé
quaze
Messages postés
9
Date d'inscription
mardi 25 juin 2013
Statut
Membre
Dernière intervention
4 février 2014
-
25 juin 2013 à 14:57
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 27 juin 2013 à 10:16
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 27 juin 2013 à 10:16
A voir également:
- Permutations d'éléments de matrice
- Photoshop elements gratuit - Télécharger - Retouche d'image
- Copier coller plusieurs éléments - Guide
- Nicolas a téléchargé le logiciel media prime. il clique sur le bouton “j’accepte” en bas à droite. quels sont les programmes ou éléments installés maintenant sur son ordinateur ? ✓ - Forum Virus
- Vous ne pouvez pas modifier une partie de matrice - Forum Excel
- Diagonale secondaire d'une matrice - Forum C
5 réponses
KX
Messages postés
16734
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
24 avril 2024
3 015
26 juin 2013 à 21:16
26 juin 2013 à 21:16
J'ai retrouvé le code que je cherchais, avant de te le donner tel quel (c'est un peu long même si tu pourras en supprimer une grande partie), voici un exemple d'utilisation qui te permettras de faire ce que tu veux (il faudra bien sûr adapter avec tes ClasseBidon ou autres)
Ce qui affichera :
Voici le code de la classe Enumerator, c'est en parti documenté et il y a quelques exemples d'utilisation dans le main...
public class TestEnumerator { public static void main(String[] args) { String[][] mat = {{"a","b"},{"c","d"},{"e","f"}}; int m = mat.length; int n = mat[0].length; Enumerator enumerator = new Enumerator(m, Enumerator.Bounds(0), Enumerator.Bounds(n), Enumerator.Bounds(1), false); while (enumerator.hasNext()) { long[] index = enumerator.next(); for (int i=0; i<m; i++) System.out.print(mat[i][(int) index[i]]); System.out.println(); } } }
Ce qui affichera :
ace acf ade adf bce bcf bde bdf
Voici le code de la classe Enumerator, c'est en parti documenté et il y a quelques exemples d'utilisation dans le main...
import java.util.Arrays; import java.util.HashSet; /** * Un énumérateur pour simuler l'imbrication de plusieurs boucles for. * On génère un tableau où chaque valeur est progressivement incrémenté à chaque pas. * * Le mode strict permet de ne conserver que les occurences qui contiennent des valeurs distinctes. */ public class Enumerator { /** * Décrit une des trois bornes de la boucle for. */ protected static class Bounds { private Long n; private long[] tab; /** * Décrit une des trois bornes de la boucle for. * L'un des deux paramètre devrait être null. * @param n entier qui remplit toutes les valeurs du tableau, ou null * @param tab le tableau qui contient toutes les valeurs du tableau, ou null */ private Bounds(Long n,long[] tab) { this.n=n; this.tab=tab; } } /** * Construit une borne de la boucle for, en imposant la même valeur entière pour toutes les boucles. * @param n l'entier de la borne * @return la borne de la boucle */ public static Bounds Bounds(long n) { return new Bounds(n,null); } /** * Construit une borne de la boucle for, en imposant toutes les valeurs du tableau. * @param tab les valeurs que doivent prendre les boucles * @return la borne de la boucle */ public static Bounds Bounds(long...tab) { if (tab==null) throw new NullPointerException(); return new Bounds(null,tab); } /** * Une exception générée lorsqu'il n'y a pas correspondance entre le nombre de boucles imbriquées et la taille des bornes. */ protected class DimensionException extends RuntimeException { private static final long serialVersionUID = 1; protected DimensionException(String message) { super(message); } } private transient final HashSet<Long> cacheStrict; /** Choix du mode strict ou non. */ protected final boolean strict; /** Le tableau des valeurs initiales (inclues). */ protected final long[] tabB; /** Le tableau des valeurs finales (exclues). */ protected final long[] tabE; /** Le tableau des valeurs d'incrémentations. */ protected final long[] tabI; /** Le tableau des valeurs courantes. */ protected final long[] tab; /** Le nombre de boucles imbriquées. */ protected final int n; /** S'il reste des valeurs à itérer. */ protected boolean has; /** * @param tab1 le tableau à initialiser * @param tab2 les valeurs du tableau de valeurs, ou null * @param val la valeur à donner à chaque case de tab1 * @param str le rôle du tableau (pour le message d'erreur) * @throws DimensionException si tab2 est de taille inférieur à n * @throws NullPointerException si tab2 et val sont tous deux null */ private void setTab(long[] tab1, long[] tab2, Long val, String str) { if (tab2==null) { if (val==null) throw new NullPointerException("Array and Integer representations of '"+str+"' Bounds can't be twice null."); for (int i=0; i<n; i++) tab1[i]=val; } else if (tab1.length<n) { throw new DimensionException("Array length of parameter '"+str+"' must be at least equals at parameter 'dim'"); } else { for (int i=0; i<n; i++) tab1[i]=tab2[i]; } } public Enumerator(int dim,Bounds begin,Bounds end,Bounds incr,boolean strict) { if (dim<=0) throw new DimensionException("Value of parameter 'dim' must be strictly positive"); else n=dim; tab = new long[n]; setTab(tab,begin.tab,begin.n,"begin"); tabB = new long[n]; setTab(tabB,begin.tab,begin.n,"begin"); tabE = new long[n]; setTab(tabE,end.tab,end.n,"end"); tabI = new long[n]; setTab(tabI,incr.tab,incr.n,"incr"); has=true; this.strict = strict; if (strict) { cacheStrict = new HashSet<Long>(n); checkStrict(); } else { cacheStrict = null; } } public Enumerator(int dim,long[] begin,long[] end,long[] incr,boolean strict) { this(dim,new Bounds(0L,begin),new Bounds(1L,end),new Bounds(1L,incr),strict); } public Enumerator(int dim,long begin,long end,long incr,boolean strict) { this(dim,Bounds(begin),Bounds(end),Bounds(incr),strict); } public boolean hasNext() { return has; } public long[] get() { long[] res = new long[n]; for (int i=0; i<n; i++) res[i]=tab[i]; return res; } protected void incr() { has=false; for (int i=n-1; i>=0; i--) { tab[i]+=tabI[i]; if ((tabI[i]>=0) ? tab[i]<tabE[i] : tab[i]>tabE[i]) { has=true; break; } else { tab[i]=tabB[i]; } } } protected void checkStrict() { while (has) { cacheStrict.clear(); for (int i=0; i<n; i++) { if (cacheStrict.contains(tab[i])) break; else cacheStrict.add(tab[i]); } if (cacheStrict.size()==n) break; else incr(); } } public long[] next() { long[] res = get(); incr(); if (strict) checkStrict(); return res; } @Override public String toString() { return "for (long i="+Arrays.toString(tabB)+"; i<"+Arrays.toString(tabE)+"; i+="+Arrays.toString(tabI)+");"; } private static void test(Enumerator e) { System.out.println(e); while (e.hasNext()) { for (long l : e.next()) System.out.print(l+" "); System.out.println(); } System.out.println(); } public static void main(String...args) { test(new Enumerator(3,0,3,1,false)); test(new Enumerator(3,0,3,1,true)); test(new Enumerator(3,Bounds(0),Bounds(3),Bounds(1),true)); test(new Enumerator(3,new long[]{0,0,0},new long[]{3,3,3},new long[]{1,1,1},true)); test(new Enumerator(3,Bounds(0,0,0),Bounds(3,3,3),Bounds(1,1,1),true)); } }
KX
Messages postés
16734
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
24 avril 2024
3 015
25 juin 2013 à 15:19
25 juin 2013 à 15:19
Pourquoi avoir pris une ArrayList<ArrayList> ? Vu ce que tu expliques, la taille de la matrice est fixe (n*m) donc un tableau à deux dimensions tab[][] aurait été plus léger (c'est une simple question de performance...)
Sinon, fais voir tes boucles for où tu t'embrouilles, ainsi que le reste de ton code, ce sera plus facile pour t'aider.
Sinon, fais voir tes boucles for où tu t'embrouilles, ainsi que le reste de ton code, ce sera plus facile pour t'aider.
quaze
Messages postés
9
Date d'inscription
mardi 25 juin 2013
Statut
Membre
Dernière intervention
4 février 2014
25 juin 2013 à 15:40
25 juin 2013 à 15:40
Disons que c'est un peu plus compliqué, mes ClasseBidon sont d'autres classes du projet, tableIteration est correctement initialisé (cf commentaires) mais ça devrait vous donner une idée :
merci beaucoup ;)
public class test { /** * @param args */ public static void main(String[] args) { ArrayList<ArrayList<ClasseBidon3>> tableIteration = new ArrayList<ArrayList<ClasseBidon3>>(); // tableIteration = this.createTable(); HERE int nbLignes= tableIteration.size(); int nbColonnes = tableIteration.get(0).size(); ClasseBidon s; ClasseBidon2 sortie; for (int i = 0; i < nbLignes; i++) { Map<String, ClasseBidon3> finalClasseBidon3 = new HashMap<String,ClasseBidon3>(); ClasseBidon3 ti = tableIteration.get(0).get(i); for (int j =1; j< nbLignes; j++) { for (int k =0; k< nbColonnes; k++) { ClasseBidon3 t = tableIteration.get(j).get(k); finalClasseBidon3.put(t.getName(),t); finalClasseBidon3.put(t.getName(),ti); s = new ClasseBidon(finalClasseBidon3); sortie.addClasseBidon(s); } } } } private class ClasseBidon { public ClasseBidon(Map<String, ClasseBidon3> finalClasseBidon3) { // TODO Auto-generated constructor stub } } private class ClasseBidon2 { public void addClasseBidon(ClasseBidon s) { // TODO Auto-generated method stub } } private class ClasseBidon3 { public String getName() { // TODO Auto-generated method stub return null; } } }
merci beaucoup ;)
quaze
Messages postés
9
Date d'inscription
mardi 25 juin 2013
Statut
Membre
Dernière intervention
4 février 2014
26 juin 2013 à 09:17
26 juin 2013 à 09:17
Je dois pas être très clair, desolé de passer par des classesBidon, mais cela me permet de pas avoir à mettre tout le code de ces classes...
Pour essayer d'expliquer plus précisement ce que je veux faire, j'ai une fonction createTable qui me renvoie une arraylist d'arraylist (je vais effectivement changer pour des tableaux) de ClasseBidon3 (une matrice d'éléments ClasseBidon3). Je combiner chaque élément de chaque ligne avec les éléments de toutes les autres lignes.
L'ordre n'a pas d'importance.
A la fin, je veux avoir un tableau contenant nbcolonnes puissance nbLigne tableau t1, ou chaque tableau t1 à exactement nombreLigne éléments. Un tableau t1 contient : un unique élément de chaque ligne pour toputes les lignes. Tous les tabelaux t1 sont différents (je veux avoir toutes les permutations possibles)
Si vous avez des idées, hésitez-pas ;) merci
Pour essayer d'expliquer plus précisement ce que je veux faire, j'ai une fonction createTable qui me renvoie une arraylist d'arraylist (je vais effectivement changer pour des tableaux) de ClasseBidon3 (une matrice d'éléments ClasseBidon3). Je combiner chaque élément de chaque ligne avec les éléments de toutes les autres lignes.
L'ordre n'a pas d'importance.
A la fin, je veux avoir un tableau contenant nbcolonnes puissance nbLigne tableau t1, ou chaque tableau t1 à exactement nombreLigne éléments. Un tableau t1 contient : un unique élément de chaque ligne pour toputes les lignes. Tous les tabelaux t1 sont différents (je veux avoir toutes les permutations possibles)
Si vous avez des idées, hésitez-pas ;) merci
KX
Messages postés
16734
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
24 avril 2024
3 015
26 juin 2013 à 09:45
26 juin 2013 à 09:45
Je ne t'ai pas oublié, mais il faudrait que je retrouve un code que j'avais déjà fait dans le genre, et là je l'ai pas sous le coude...
quaze
Messages postés
9
Date d'inscription
mardi 25 juin 2013
Statut
Membre
Dernière intervention
4 février 2014
26 juin 2013 à 09:53
26 juin 2013 à 09:53
Merci ;)
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Merci beaucoup !
Je vais pas faire le difficile mais je m'interroge quand même sur la possibilité de le faire plus "simplement", ie avec quelques boucles for...
En tout cas, j'ai adapté à mon projet, ca marche tout bien c'est parfait, merci !
Je vais pas faire le difficile mais je m'interroge quand même sur la possibilité de le faire plus "simplement", ie avec quelques boucles for...
En tout cas, j'ai adapté à mon projet, ca marche tout bien c'est parfait, merci !
KX
Messages postés
16734
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
24 avril 2024
3 015
27 juin 2013 à 10:16
27 juin 2013 à 10:16
Le problème des boucles for c'est qu'il en faudrait un nombre variable imbriquées les unes dans les autres, ce qu'il est impossible à faire de manière générale.
Si je reprends l'exemple que je t'ai donné, ma classe Enumerator est équivalente à ceci (à vérifier)
Il est évident qu'avec ce code tu ne pourras jamais traiter d'autres matrices que celles de dimension 3, si tu devais traiter d'autres tailles tu devrais changer le code, ce qui est peu intéressant en programmation objet.
Moi j'avais fait ce code de manière suffisamment générale pour pouvoir être utilisé dans le plus grand nombre de cas possibles. Par exemple ton problème se résout immédiatement avec cette classe, sans avoir grand chose à coder en plus. Mais du coup une grande partie de mon code ne te sers pas, car il est destiné à d'autres usages,en particulier la gestion des permutations sans doublon, tu pourrais donc faire du ménage et ne garder que ce qui t'est vraiment utile.
Il peut cependant être intéressant de tout garder au cas où un jour tu veuilles modifier ton code et utiliser une fonctionnalité dont tu n'as pas utilité aujourd'hui mais qui serait déjà prise en charge par mon code... C'est tout l'intérêt de faire des classes les plus complètes possibles !
Si je reprends l'exemple que je t'ai donné, ma classe Enumerator est équivalente à ceci (à vérifier)
public class TestEnumerator { public static void main(String[] args) { String[][] mat = {{"a","b"},{"c","d"},{"e","f"}}; long[] index = new long[3]; for (index[0]=0; index[0]<2; index[0]++) for (index[1]=0; index[1]<2; index[1]++) for (index[2]=0; index[2]<2; index[2]++) { for (int i=0; i<3; i++) System.out.print(mat[i][(int) index[i]]); System.out.println(); } } }
Il est évident qu'avec ce code tu ne pourras jamais traiter d'autres matrices que celles de dimension 3, si tu devais traiter d'autres tailles tu devrais changer le code, ce qui est peu intéressant en programmation objet.
Moi j'avais fait ce code de manière suffisamment générale pour pouvoir être utilisé dans le plus grand nombre de cas possibles. Par exemple ton problème se résout immédiatement avec cette classe, sans avoir grand chose à coder en plus. Mais du coup une grande partie de mon code ne te sers pas, car il est destiné à d'autres usages,en particulier la gestion des permutations sans doublon, tu pourrais donc faire du ménage et ne garder que ce qui t'est vraiment utile.
Il peut cependant être intéressant de tout garder au cas où un jour tu veuilles modifier ton code et utiliser une fonctionnalité dont tu n'as pas utilité aujourd'hui mais qui serait déjà prise en charge par mon code... C'est tout l'intérêt de faire des classes les plus complètes possibles !