So I am trying to return another String from 2 input sentences zipped together. If the 2 sentences are identical in length it will produce an actual output. If the two input sentences are not identical in length then it will just return an empty string. Here is my code so far but I can’t figure out how to zip the words correctly could someone help me. BTW it would be nice if you could help me by doing this recursively because I’m trying to practice that.
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); } }
Advertisement
Answer
I love your class name. Sincerely
In order to really “return” it, you could implement something similar to the examples below.
Update/Edit: The original answer is below, as the three new approaches (which don’t care about the number of strings to zip) are on top.
[MultiThreaded
]
Each of the words to zip is handled by a thread. Why? Ask yourself: WHY NOT???
Boredom makes this things happen.
Each word will be lovely processed by its own thread. Threads organize themselves in order not to process the same word and set the same positions thanks to the 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*/
Was this required by any means? OF COURSE NOT. But it was fun, and my girlfriend told me to do it.
Lie, I don’t have a girlfriend. Do you really think I’d be doing this if I had one??
[Zip'em all
]
Two different approaches:
1. Direct move
Works regardless of the number of strings to zip, from 2 to n.* This means these approaches are also the replacement of the old methods, as you can either call getStringsZippedDirectMove("ABC,"123")
or getStringsZippedDirectMove(yourArray)
.
In this approach, each string is completely allocated at a time, so each element in the list is only accessed/processed once. The main loop iterates based on the number of elements in the array:
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; }
For example, for the first String: “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
For the last String: “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
Same output:
String[] mix =new String[] { "AAA","123","BBB","456","CCC","789"}; System.out.println(getStringsZippedDirectMove(mix)); //"A1B4C7A2B5C8A3B6C9"
Each iteration leads to the complete relocation of the String element’s chars.
2. Multi move from index – Holger style
Motivated by Holger’s comments
This also will work regardless of the number of strings to zip, from 2 to 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); }
The main loop iterates three times, as it’s based on each text’s length (3). At each iteration, it will append the char at position i
from each of the Strings in the array in the index marked by j
. This last counter increments at each assignation.
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 "));
Original answer block (2 strings)
Arrays
Double assignation at each iteration
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" */ }
Loop over the length of any of the Strings and insert each element in order. During the iterations, this are the assigned values:
i = 0 i = 1 i = 2 -------------------------------------------------------- zip[0] = A zip[2] = B zip[4] = C zip[1] = 1 zip[3] = 2 zip[5] = 3
Horrendous paint:
As a result, we got:
zip = ['A','1','B','2','C','3']
|||
new String(zip) = "A1B2C3"
Note: If you don’t love arrays, you have no hearth.
Single assignation at each iteration
This uses another approach for the iteration logic, which seems totally useless when you can do what the previous example does. but just for fun.
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" }
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" }
Probably the worst performant approach.
String#charAt
Note that charAt()
, correctly pointed out on Elliot‘s answer, will not work with this logic; it will give you a numeric text, as result of adding their respective unicode values. It won’t append the characters.
Alternatives to work with charAt()
would be using the empty string workaround, or creating a char[]
as in the second boring example.
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" }