4 votes

Chaîne zippée à partir de 2 chaînes (ou plus) - "AB" + "YZ" = "AYBZ".

J'essaie donc de renvoyer une autre chaîne à partir de deux phrases d'entrée assemblées. Si les deux phrases sont de longueur identique, il produira une sortie réelle. Si les deux phrases d'entrée ne sont pas de même longueur, il renverra simplement une chaîne vide. Voici mon code jusqu'à présent mais je n'arrive pas à trouver comment zipper les mots correctement, quelqu'un pourrait-il m'aider ? De plus, ce serait bien si vous pouviez m'aider à faire cela de manière récursive, car j'essaie de m'entraîner.

Ex :

Zippppp("ABC", "123") will return "A1B2C3"
Zippppp("AD", "CCC") will return “”

public class Zippppp
{
    public Zippppp(String a, String s)
    {
       int l1 = a.length();
       int l2 = s.length();
       if(l1 == l2)
          for(int i = 0; i > l1; i++)          
             System.out.print( a.substring(0, 1) + s.substring(0, 1));
     }

     public static void main(String args[ ])
     {
        Zippppp sv = new Zippppp("ABC", "123");
        System.out.print(sv);
     }
}

11voto

Asier Aranbarri Points 1834

J'adore le nom de votre classe. Je vous prie d'agréer, Madame, Monsieur, l'expression de mes salutations distinguées.

Pour vraiment " retour ", vous pourriez mettre en œuvre quelque chose de similaire aux exemples ci-dessous.

Mise à jour/Modification : La réponse originale est ci-dessous, car les trois nouvelles approches (qui ne se soucient pas du nombre de chaînes à zipper) sont en haut.


[ MultiThreaded ]

_Le ZIPPER ultime_

Chacun des mots à zipper est traité par un thread. Pourquoi ? Posez-vous la question : POURQUOI PAS ?

L'ennui est à l'origine de ce genre de choses.

Chaque mot sera traité de manière adorable par son propre fil. Les threads s'organisent pour ne pas traiter le même mot et mettre les mêmes positions grâce à la fonction AtomicInteger .

String[] mix =new String[]{"AAAZZZ","100001","BBBWWW","200002","CCCYYY","300003",
                           "DDDXXX", "400004","EEEWWW","5000005","FFFVVV","600006"};

int strl = mix[0].length();        //entry's length
int nwords = mix.length;           //number of strings
char[] zip=new char[strl*nwords];  //the result

AtomicInteger myWord = new AtomicInteger(0);
//returning boolean if want to check some future failed(not here lol)
List<Callable<Boolean>> callables = new ArrayList<>(nwords);  
Callable<Boolean> zipYours =
    new Callable<Boolean>() 
    {  
        public Boolean call() 
        {  
           try
           {
              int mine = myWord.getAndIncrement();
              for (int x=0; x < strl; x++)
                  zip[mine+(nwords*x)]=mix[mine].charAt(x);

            }catch(Exception e) {
               return false;
            }               

            return true;
         }  
     };

 for (int i=0;i<nwords;i++)
      callables.add(zipYours);

 //one thread - one word - true loef
 ExecutorService executor = Executors.newFixedThreadPool(nwords);
 executor.invokeAll(callables);  
 executor.shutdown();  

 System.out.println(new String(zip));
 /*A1B2C3D4E5F6A0B0C0D0E0F0A0B0C0D0E0F0Z0W0Y0X0W0V0Z0W0Y0X0W0V0Z1W2Y3X4W0V6*/

Était-ce une obligation quelconque ? BIEN SÛR QUE NON. Mais c'était amusant et ma petite amie m'a dit de le faire.

Mensonge, je n'ai pas de petite amie. Tu crois vraiment que je ferais ça si j'en avais une ?


Zip'em all --- Chaînes multiples


1. Déplacement direct

Fonctionne quel que soit le nombre de chaînes à zipper, de 2 à n Cela signifie que ces approches remplacent également les anciennes méthodes, puisque vous pouvez soit appeler getStringsZippedDirectMove("ABC,"123") o getStringsZippedDirectMove(yourArray) .

Dans cette approche, chaque chaîne est entièrement allouée à la fois, de sorte que chaque élément de la liste n'est accessible/traité qu'une seule fois. La boucle principale itère en fonction du nombre d'éléments du tableau :

public static String getStringsZippedDirectMove(String... mix) 
{    
   if (!goodMix(mix))
       return "woloolooO";                //you are a blue monk now

   int cn = mix[0].length(), n = mix.length;   //cn = 3 | n = 6 
   char[] zip=new char[cn*n];

   for (int i=0; i<n; i++) 
       for (int x=0; x<cn; x++)
           zip[i+(n*x)] = mix[i].charAt(x);

   return  new String(zip);  
}

boolean goodMix(String ... mix)
{
   if (mix.length<2) 
      return false;              
   for (int i=1; i<mix.length; i++)
      if (mix[i].length()!=mix[0].length())
         return false;        
   return true;
}

Par exemple, pour la première chaîne : " AAA " :

zip[i+(n*x)]=mix[i].charAt(x); // zip[0 + (6*0)]=mix[0].charAt(0); 
zip[i+(n*x)]=mix[i].charAt(x); // zip[0 + (6*1)]=mix[0].charAt(1);
zip[i+(n*x)]=mix[i].charAt(x); // zip[0 + (6*2)]=mix[0].charAt(2); 

            zip[0]=A      zip[6]=A     zip[12]=A  

Pour la dernière chaîne : " 789 " :

zip[i+(n*x)]=mix[i].charAt(x); // zip[5 + (6*0)]=mix[5].charAt(0); 
zip[i+(n*x)]=mix[i].charAt(x); // zip[5 + (6*1)]=mix[5].charAt(1);
zip[i+(n*x)]=mix[i].charAt(x); // zip[5 + (6*2)]=mix[5].charAt(2); 

            zip[5]=7      zip[11]=8     zip[17]=9  

enter image description here

Même résultat :

 String[] mix =new String[] { "AAA","123","BBB","456","CCC","789"};
 System.out.println(getStringsZippedDirectMove(mix));   //"A1B4C7A2B5C8A3B6C9"

Chaque itération conduit à la relocalisation complète des caractères de l'élément String.


2. Déplacement multiple à partir de l'index - Style Holger

Motivé par les commentaires de Holger

Cela fonctionne également quel que soit le nombre de chaînes à zipper, de 2 à n .*

public String getStringsZippedHolger(String ... mix) 
{    
   if (!goodMix(mix))
      return "woloolooO";           //you are a red monk now

   char[] zip = new char[mix[0].length()*mix.length];    
   for (int i=0, j=0; i<mix[0].length(); i++) 
      for (String s : mix)
          zip[j++] = s.charAt(i);

   return new String(zip);  
}

La boucle principale itère trois fois, car elle est basée sur la longueur de chaque texte (3). À chaque itération, elle ajoute le caractère à la position i à partir de chacune des chaînes du tableau à l'index marqué par j . Ce dernier compteur s'incrémente à chaque assignation.

enter image description here

 String[] mix =new String[] { "AAA","123","BBB","456","CCC","789"};
 System.out.println(getStringsZippedHolger(mix));               // "A1B4C7A2B5C8A3B6C9"

 System.out.println(getStringsZippedHolger("HLE","OGR"));
 System.out.println(getStringsZippedHolger("IT S","SHBS"," EO "));


Bloc de réponses original (2 chaînes)

Arrays

Double assignation à chaque itération

public String getZippppppppppppppppppppppppp(String a, String s)  //a -"ABC" s -"123"
{    
   if (s.length()!=a.length())
      return "";
   char[] zip=new char[s.length()*2];      
   for (int i=0; i<s.length(); i++) 
   {
      zip[i*2] = a.charAt(i);   
      zip[(i*2)+1] = s.charAt(i);  
   }  
   return new String(zip);  /* "A1B2C3" */
}

Bouclez sur la longueur de n'importe quelle chaîne et insérez chaque élément dans l'ordre. Pendant les itérations, voici les valeurs attribuées :

             i = 0              i = 1             i = 2
      --------------------------------------------------------
            zip[0] = A        zip[2] = B         zip[4] = C
            zip[1] = 1        zip[3] = 2         zip[5] = 3

Peinture épouvantable :

enter image description here

En conséquence, nous avons obtenu :

zip = ['A','1','B','2','C','3'] ||| new String(zip) = "A1B2C3"

Note : Si vous n'aimez pas les tableaux, vous n'avez pas de cœur.

Une seule assignation à chaque itération

Ceci utilise une autre approche pour la logique d'itération, qui semble totalement inutile quand on peut faire ce que l'exemple précédent fait. mais juste pour le plaisir.

static String getZipppppppppppppppppppppUsingCharAtThanksElliot(String a, String s)  
{                                                                 //a -"ABC" s -"123"
  if (a.length()!=s.length()) 
      return "";
  char[] zip = new char[s.length()*2];
  int c=0;
  boolean even = false;
  for(int i =0; i < (s.length()*2); i++) 
  {
     even =!even;
     if (even) 
        zip[i] = a.charAt(c); 
     else 
     {      
        zip[i] = s.charAt(c);
        c++; 
     }   
   }

   return new String(zip);  //--> "A1B2C3"
}

Utilisation String#subString :

public String getZippppppppppppppppppppppppp(String a, String s)  //a -"ABC" s -"123"
{
    if (a.length()!=s.length()) 
        return "";
    String line="";
    for(int i = 0; i < s.length(); i++)
        line += ( a.substring(i*1, (i*1)+1) + s.substring(i*1, (i*1)+1) );

    return line;  //--> "A1B2C3"
}

Il s'agit probablement de l'approche la moins performante.


Utilisation String#charAt

Il convient de noter que charAt() , a souligné à juste titre sur le site Elliot ne fonctionnera pas avec cette logique ; elle vous donnera un texte numérique, résultant de l'addition de leurs valeurs unicode respectives. Elle n'ajoutera pas les caractères.

Alternatives pour travailler avec charAt() serait d'utiliser le solution de contournement pour les chaînes vides ou la création d'un char[] comme dans le deuxième exemple ennuyeux.

public String getZipppppppppppppppppppppUsingCharAtThanksElliot(String a, String s)  
{                                                                 //a -"ABC" s -"123"
    if (a.length()!=s.length()) 
        return "";
    String line="";
    for(int i = 0; i < s.length(); i++)
        line +=  a.charAt(i) + "" + s.charAt(i) ; //note the empty string

    return line;  //--> "A1B2C3"
}

2voto

Elliott Frisch Points 45093

Vous êtes en train d'instancier Zippppp et l'impression en tant qu'effet secondaire de l'instanciation. Ce n'est pas la raison d'être d'un constructeur. static et renvoie un String . Et utiliser un StringBuilder . Quelque chose comme,

public static String Zippppp(String a, String s) {
    StringBuilder sb = new StringBuilder();
    if (a != null && s != null && a.length() == s.length()) {
        for (int i = 0; i < a.length(); i++) {
            sb.append(a.charAt(i)).append(s.charAt(i));
        }
    }
    return sb.toString();
}

Et ensuite de l'appeler

System.out.println(Zippppp("ABC", "123"));

2voto

Thiyanesh Points 2305

Ne pas utiliser charAt , substring sur cordes

  1. Utilisation charAt y substring suppose que les caractères du String sont dans le plan multilingue de base (BMP)
  2. Pour tout caractère dans le plan supplémentaire (SP), ces hypothèses donneront des caractères non valides.

Utiliser le point de code

  1. Les points de code doivent devenir la règle par défaut et toute transformation avec des points de code est interdite. char devrait être obsolète
  2. Utiliser la goyave Streams.zip (il s'agit d'une version bêta pour de très longues années et nous pouvons en dépendre)

    import com.google.common.collect.Streams; import java.util.stream.Collectors;

    class Zippppp { private final String zipped; public Zippppp(String a, String b) { zipped = Streams.zip(a.codePoints().boxed(), b.codePoints() .boxed(), (x, y) -> new String(Character.toChars(x)) + new String(Character.toChars(y))) .collect(Collectors.joining()); }

    public static void main(String[] args){
        System.out.println(new Zippppp("\uD83D\uDE00\uD83D\uDE00\uD83D\uDE00", "123").zipped); // 123
        System.out.println(new Zippppp("ABC", "12").zipped); // A1B2
    }

    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X