Générer un string de taille variable

Fermé
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 - 18 mai 2015 à 02:15
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 - 18 mai 2015 à 23:50
Salut tout le monde,

Etant donné, un String str ={"1 2 3"}, je veux générer tous les sous-élements de str donc, je dois avoir comme résultat : 1 2, 1 3, 2 3.

on peut fair ça avec ce bout de code

for (int j = 0; j < str.length-1; j++) {
for (int i = j + 1; i < str.length; i++) {
String d = str[j] + " " + str[i];

}
}


Ceci donne le résultat : 1 2 , 1 3, 2 3

Mais mon probléme je peux avoir un string comme çà 1 2 3 4, donc je dois avoir ce résultat : 1 2 3, 1 2 4, 1 3 4, 2 3 4

Et ainsi de suite : quelque soit la taille d'un String avec des éléments ordonnés, je dois extraire ces sous éléments de taille-1.

J'ai écris un code qui se base sur les List et je parts de l'idée de retirer le dernier élément et ensuite j'utilise StringTokenizer, le code marche bien, mais je veux un code qui sera plus rapide car je dois faire ce traitement pour faire des comparaison après, et ceci pour des String de taille considérable.


Une idée pour y arriver ?

Merci beaucoup

3 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
18 mai 2015 à 11:12
Bonjour,

Tu peux regarder ce code et l'adapter à ton besoin.

Par exemple :

import ccm.kx.enumerator.Enumeration;

public class Test {

    public static void main(String[] args) {

        String str = "1234";
        int n = str.length() - 1;

        Enumeration e = new Enumeration(n, 0, n, 1, true);

        char[] tmp = new char[n];

e:      for (long[] tab : e) {

            for (int i = 0; i < n - 1; i++)
                if (tab[i] > tab[i + 1])
                    continue e; // on ne garde que les combinaisons dans l'ordre

            for (int i = 0; i < n; i++)
                tmp[i] = str.charAt((int) tab[i]);

            System.out.println(new String(tmp));
        }
    }
}
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
18 mai 2015 à 13:12
C'est très intéressant ce code.merci bcp
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
18 mai 2015 à 13:25
j'ai commencé à faire ce programme.

public class ConcurrentStringTokenIzer {

public static void main(String[] args) {

List<String> list = new ArrayList<>();
List<String> listTemp1 = new ArrayList<>();

//Generate Elements of the list
for (int i = 0; i < 10; i++) {
list.add(Integer.toString(i) + " " + Integer.toString(i + 1) + " "
+ Integer.toString(i + 2) + " "
+ Integer.toString(i + 3));
}

for (String list1 : list) {

String d = new String();


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

for (int j = list1.length(); j >0; j=j-2) {

if(j == list1.length()){
d = list1.substring(i,j-2).trim();
if(d.length()<list1.length()-2)
break;
}
else{
d = list1.substring(i,j-1)+list1.substring(j+1,list1.length()).trim();
}


}


}

}

}

}


Mais pour les éléments ayant plus de 1 caractéres ça ne marche. une idée stp? merci
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
18 mai 2015 à 19:46
Il y a un
h
qui se promène dans
for (int i = 0; i<h; i++)
que vaut il ?

De plus, ton code ne fait rien...
Tes boucles modifient
d
mais il n'est jamais utilisé nul part.

"pour les éléments ayant plus de 1 caractéres ça ne marche."
Même pour 1 caractère, je ne vois pas trop ce qui fonctionne...

À mon avis les substring sont une mauvaise idée de départ, surtout si tu cherches à optimiser le temps de traitement. Il faudrait plutôt travailler sur les tableaux de caractères (et en particulier supprimer les espaces entre deux chiffres)

String str = "1234";
char[] tab = str1.toCharArray();
String str2= new String(tab);
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
18 mai 2015 à 20:36
Salut KX,
J'ai écrit ce code et ça marche pour moi, pour des tailles variables.

package iteratortest;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

public class test2 {


public static void main(String[] args) {
String list1 = "111 222 333 444";
String d = "";
int k = 0;
List<Integer> list = new ArrayList<>();
int l = 0;
while (k >= 0) {

k = list1.indexOf(" ", k + 1);
System.out.println(k);
if (k > 0) {
list.add(k);
}
l++;

}

for(int index = 0; index<list.size(); index++){
if (index == 0) {
d = list1.substring(list.get(index) + 1, list1.length()).trim();
System.out.println(d);
}
if (index == list.size()-1) {
d = list1.substring(0, list.get(index) + 1).trim();
System.out.println(d);
break;
} else if (index < list.size()) {
d = list1.substring(0, list.get(index) + 1)+ list1.substring(list.get(index+1), list1.length()).trim();
System.out.println(d);
}
}

}

}



et le résultat est le suivant :
222 333 444
111 333 444
111 222 444
111 222 333

S'il y a quelques optimisations à faire, j'en suis remerciant. j'utilise ce bout ce de code pour comprarer des uses cases pour l'algorithme Apriori modifié
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
18 mai 2015 à 20:39
pour une chaine = "1 22 333 4444 55555"

le résultat est :
22 333 4444 55555
1 333 4444 55555
1 22 4444 55555
1 22 333 55555
1 22 333 4444
0
kharchafi Messages postés 9 Date d'inscription jeudi 14 mai 2015 Statut Membre Dernière intervention 18 mai 2015
18 mai 2015 à 21:42
Bonsoir tous le monde,
Je vous propose le code suivant :
public class Main
{
public static void main(String[] args)
{
String str="1 2 3 4 5", result="";
str = str.replace(" ",""); // supprimer les espaces
int n = str.length();

for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
if(j != n-1-i)
result += str.charAt(j)+" ";
if(i != n-1)
result += ", ";
}
System.out.println(result);
}
}
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
18 mai 2015 à 21:47
C'est également ce que je proposais ici, à part que je l'ai pris dans le cas général des String (donc avec un split, plutôt qu'un replace/charAt).
0
kharchafi Messages postés 9 Date d'inscription jeudi 14 mai 2015 Statut Membre Dernière intervention 18 mai 2015 > KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024
18 mai 2015 à 22:09
Bonsoir,
Vous avez supprimer la diagonale, alors en fait, vous devez supprimer l'anti-diagonale.
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
18 mai 2015 à 22:14
Merci
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
18 mai 2015 à 22:15
En faisant la "diagonale" ou "l'anti-diagonale" ça devrait juste changer l'ordre dans lesquels les résultats vont apparaître, mais je ne pense pas que ce soit vraiment important.

En plus, j'obtiens le même résultat que dans l'exemple de neocol :
22 333 4444 55555 
1 333 4444 55555 
1 22 4444 55555 
1 22 333 55555 
1 22 333 4444 
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
18 mai 2015 à 22:27
oui effectivement l'ordre n'est pas important car, je devrais comprarer tous ces éléments avec d'autres et utiliser un compteur en cas matches
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
18 mai 2015 à 22:14
Wé ton code est beaucoup plus simple. merci beaucoup.

J'ai une autre question stp, après la sortie de ce code, je dois ces strings avec les strings d'une autre list, est-ce-qu'il y a possibilité qu'on fasse une comapraison et en même temps générer d'autres éléments.

Je m'explique : imaginons que j'ai List<String> a=[1 2 3, 4 5 6 ] donc je dois générer tous les sous-ensembles de a a1= [1 2, 1 3, 2 3] , a2 = [4 5, 4 6, 5 6] , ces éléments ai je dois les comprarer avec d'autres éléments d'une autres List.

est-ce-que c'est possible que dés que je génére les sous-ensembles d'un élément de la List a(par exemple [1 2 3] donc j'aurais a1= [1 2, 1 3, 2 3])je les compare avec les autres éléments de l'autre List b, et en même je génére les autres éléments du deuxiéme éléments de la List ([4 5 6]) et dès que la premiére comparaison ( des élements a1= [1 2, 1 3, 2 3]) est finie on passe à la deuxiéme comparaison des éléments (a2 = [4 5, 4 6, 5 6]).

C'est faire deux traiements en même temps.

Je ne sais pas si les Threads permettent de faire ce travail?

merci
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
18 mai 2015 à 23:20
Il faut arrêter de penser aux String pour manipuler des ensembles d'éléments, ce n'est pas la bonne manière de voir les choses, réfléchis plutôt en terme de listes.

Tu aurais donc a = [[1,2,3],[4,5,6]] et b = [[[1,2],[1,3],[2,3]],[[4,5],[4,6],[5,6]]]

Remarque : vu ton besoin, utiliser des SortedSet serait plus pertinent que les List.

Alors ensuite j'avoue m'être un peu perdu dans ton explication, mais il me semble que ce dont tu as besoin ce sont des files.

Thread 1 : ajout de [1,2,3] et [4,5,6] dans la File 1
Thread 2 : choisis un élément de File 1, par exemple [1, 2, 3], calcule les combinaisons et les ajoutes au fur et à mesure dans la File 2, donc [1, 2], [1, 3], [2, 3], puis recommence tant qu'il y a des éléments dans la File 1
Thread 3 : choisis un élément de File 2, par exemple [1, 2], le compare dans la deuxième liste, mets le résultat dans File 3, et recommence tant qu'il y a des éléments dans la File 2
Thread 1 : récupère les résultats dans File 3.

Remarque : ce serait encore plus rapide si tu avais N ordinateurs pour assurer le rôle de Thread 2 et N² ordinateurs pour assurer le rôle de Thread 3, dans ce cas chaque ordinateur ne traiterait qu'une seule combinaison.

Remarque : comme je n'ai aucune information sur la deuxième liste, et sur la comparaison que tu veux faire, je ne sais pas si ce que je dis est pertinent.
Il est parfois plus rapide (avec l'algo qui va bien) de comparer toutes les combinaisons en une fois (surtout quand elles sont triées). Un découpage logique des données permet de diminuer la complexité de l'algorithme, ce qui est plus efficace que de multiplier les threads sur un algorithme coûteux.
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
18 mai 2015 à 23:50
Ok, je vais voir l'utilisation des SortedSet.

Merci beaucoup KX
0