Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

allswap swapping all characters

Hi,
http://codingbat.com/prob/p134133
I am trying to solve challenge

We'll say that 2 strings "match" if they are non-empty and their first chars are the same. Loop over and then return the given array of non-empty strings as follows: if a string matches an earlier string in the array, swap the 2 strings in the array. When a position in the array has been swapped, it no longer matches anything. Using a map, this can be solved making just one pass over the array. More difficult than it looks.


allSwap(["ab", "ac"]) → ["ac", "ab"]
allSwap(["ax", "bx", "cx", "cy", "by", "ay", "aaa", "azz"]) → ["ay", "by", "cy", "cx", "bx", "ax", "azz", "aaa"]
allSwap(["ax", "bx", "ay", "by", "ai", "aj", "bx", "by"]) → ["ay", "by", "ax", "bx", "aj", "ai", "by", "bx"]

i was not very clear on the approach and above description as well.

How to design and code and test above kind of challenges? please advise
SOLUTION
Avatar of dpearson
dpearson

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

We'll say that 2 strings "match" if they are non-empty and their first chars are the same. Loop over and then return the given array of non-empty strings as follows: if a string matches an earlier string in the array, swap the 2 strings in the array. When a position in the array has been swapped, it no longer matches anything. Using a map, this can be solved making just one pass over the array. More difficult than it looks.
not clear on this description. can you please elaborate
Avatar of dpearson
dpearson

A match happens if the first characters of the string match - so "abcdef" has first char "a" and matches anything else starting with "a".

Make sense?
Avatar of gudii9

ASKER

A match happens if the first characters of the string match - so "abcdef" has first char "a" and matches anything else starting with "a".
in above example there is no other a after first a so that is not a case/example of match??
still not clear

We'll say that 2 strings "match" if they are non-empty and their first chars are the same

so we need to have 2 string for example
 xyz , xlm?
in above 2 stings both start with x so they considered match?


Loop over and then return the given array of non-empty strings as follows:
how to loop over and return


step 1;
if a string matches an earlier string in the array, swap the 2 strings in the array.
what above means xyz xml are 2 strings since x matched it becomes xml xyz?


step 2:
When a position in the array has been swapped, it no longer matches anything.

what above means?


step 3:
Using a map, this can be solved making just one pass over the array. More difficult than it looks.

how to do using map?? what it means by one pass over the array?
Avatar of gudii9

ASKER

please advise
xyz , xlm?
in above 2 stings both start with x so they considered match?
Yes

what above means xyz xml are 2 strings since x matched it becomes xml xyz?
yes

When a position in the array has been swapped, it no longer matches anything.
If you have the strings abc, ade, axy, azz they all start with 'a' so they all match.  But once you swap a pair you don't keep doing it.
So you do:
abc swap ade and now your list is ade, abc, axy, azz
but axy doesn't swap with abc (because abc already was moved) so you instead get
axy swaps with azz and the final list is ade, abc, azz, axy

how to do using map??
This just means that a Map data structure is used in the algorithm.  Which you can see it does.
Map<Character, Integer> map = new HashMap<>() ;

Open in new window


what it means by one pass over the array?
You only have to loop through the array one time.   There's a single loop:
for (int i = 0 ; i < strings.length ; i++) 

Open in new window


I think you understand this better than you realize.  I think you've got it.

Doug
Avatar of gudii9

ASKER

String swap = strings[i] ;//asign strings array i index thing to string swap ??
      strings[i] = strings[match] ;//asign strings array match index thing to strings at index i ??
      strings[match] = swap ;//asign  swap string to strings array match index thing ??


can you please elaborate on above  3lines?

Open in new window

Can you understand what these 3lines below do?

int swap = si;
  si = sm;
  sm = swap;
Avatar of gudii9

ASKER

int swap = si;//assigning si to int swap then assign sm to si then assign swap (which has si value) to sm(whose orignal value given to si) so we are
                       //swapping si and sm values with some dummy intermediate swap constnat??
  si = sm;
  sm = swap;
so now that you understand the code in https:#a42351765 does that elucidate the code in https:#a42351424 ?
Avatar of gudii9

ASKER

Integer match = map.get(firstChar) ;
what is match above means and below line means
 strings[i] = strings[match] ;

Open in new window

"match" is  just the name of a local Integer variable.  it doesn't really mean anything, any arbitrary name could have been used in its place.
But programmers may sometimes choose variable names that remind them of what they want to use the variable for.
Avatar of gudii9

ASKER

for example allSwap(["ab", "ac"]) → ["ac", "ab"]


Map<Character, Integer> map = new HashMap<>() ;
  
  for (int i = 0 ; i < strings.length ; i++) {
    Character firstChar = strings[i].charAt(0) ;//firsrChar is "a" right from "ab"?
    Integer match = map.get(firstChar) ;//match is what?? map.get(a) is null right for the first time in this case for "ab"? what is this match for next iteration of "ac"??

Open in new window

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

when 0 has been put in map.put("a", 0),  map.get("a") will be 0
we are not putting 0 anywhere right?
Avatar of gudii9

ASKER

 for (int i = 0 ; i < strings.length ; i++) {
    Character firstChar = strings[i].charAt(0) ;
    Integer match = map.get(firstChar) ;

    if (match == null) {
       // This is the first time we've seen this first letter
      map.put(firstChar, i) ;
    }

Open in new window

i see for ab firstChar is a and match ie map.get(a) is null
so next line if condition match null matches and we are puting map first entry as first char and i i.e a,0
Avatar of gudii9

ASKER

for second iternation ac we are pasing which goes through  else loop not if loop?

} else {
      // We've seen this same first letter before so swap the two entries
      String swap = strings[i] ;
      strings[i] = strings[match] ;
      strings[match] = swap ;

      // And they say once you've done a swap you can't swap
      // again so remove it from the map.
      map.remove(firstChar) ;
    }
  }
  

Open in new window

Avatar of gudii9

ASKER

  for (int i = 0 ; i < strings.length ; i++) {
    Character firstChar = strings[i].charAt(0) ;
    Integer match = map.get(firstChar) ;

Open in new window

for second iteration since map has a,0
first charactr of ac is a so match is map.get(a) which is 0 which is non null so goes to else loop?
 else {
      // We've seen this same first letter before so swap the two entries
      String swap = strings[i] ;
      strings[i] = strings[match] ;
      strings[match] = swap ;

      // And they say once you've done a swap you can't swap
      // again so remove it from the map.
      map.remove(firstChar) ;
    }

Open in new window

I might prefer to say "for loop", "if condition", "else condition" , but you seem to be following so far.
Avatar of gudii9

ASKER

else {
      // We've seen this same first letter before so swap the two entries
      String swap = strings[i] ;
      strings[i] = strings[match] ;
      strings[match] = swap ;

      // And they say once you've done a swap you can't swap
      // again so remove it from the map.
      map.remove(firstChar) ;
    }

here assigning strings[1] i.e ac to swap dummy temporary variable for some time
then strings[i] ie string[1] assing strings[match] ie strings[0] ie ab 
then strings[0] assinging swap ie ab
so now strings[0] has ac and strings[1] has ab

Open in new window

Avatar of gudii9

ASKER

for example allSwap(["ab", "ac","ax", "ay"]) → ["ac", "ab", "ay","ax"]

how 3rd iterattion ax 4th iteration ay works


why this thinking is stretching me so much


understanding solution taking this much time how to write this kid of code.

how to become strong in writing this kind of code using
for loop ,if loop, collection api hashmap, array basically touching all areas of core java except multi threads?
Avatar of gudii9

ASKER

 // And they say once you've done a swap you can't swap
      // again so remove it from the map.
      map.remove(firstChar) ;

Open in new window


why are they removing this? if they remove firstChar from map then corresponding value aslo removed?
map.remove("a") makes map.get("a") become null
Avatar of gudii9

ASKER

how above different from below firstSwap solution where
  // And they say once you've done a swap you can't swap
      // again so mark as disabled in the map.
      map.put(firstChar, -1) ;

public String[] firstSwap(String[] strings) {
  // The map is from the first character in the string to its position in the array.
  Map<Character, Integer> map = new HashMap<>() ;
  
  for (int i = 0 ; i < strings.length ; i++) {
    Character firstChar = strings[i].charAt(0);
    Integer match = map.get(firstChar);

    if ((match == null)) {
       // This is the first time we've seen this first letter
      map.put(firstChar, i);
    } else if (match != -1) {
      // We've seen this same first letter and havent swapped yet, so swap the two entries
      String swap = strings[i];
      strings[i] = strings[match];
      strings[match] = swap;

      // And they say once you've done a swap you can't swap
      // again so mark as disabled in the map.
      map.put(firstChar, -1) ;
    }
  }
  
  return strings;
}

Open in new window

Avatar of gudii9

ASKER

I might prefer to say "for loop", "if condition", "else condition" , but you seem to be following so far.

i agree , i remember this if else condition not loop ...for loop
Avatar of gudii9

ASKER

for example allSwap(["ab", "ac","ax", "ay"]) → ["ac", "ab", "ay","ax"]

how 3rd iterattion ax 4th iteration ay works

since we executed below line
   map.remove(firstChar) ;

map entry a,0 is deleted
map is empty for 3rd iteration ax
first char again is a from ax
now map.get(a) is match which is null now


so if match null we are putting map.put(firstChar, i) ; ie we have put entry a,2 now (instead of a,0 for first iternation
Avatar of gudii9

ASKER

now for fourth iteration ay

else loop as match is not null since first character is a from ay and the map.get(a) is 2 now which is match

} else {
      // We've seen this same first letter before so swap the two entries
      String swap = strings[i] ;
      strings[i] = strings[match] ;
      strings[match] = swap ;

      // And they say once you've done a swap you can't swap
      // again so remove it from the map.
      map.remove(firstChar) ;
    } here in swap we are assiging strings[2] ie ax then strings[2] assigned with vaue strings match which is strigns[2] again???

Open in new window

Avatar of gudii9

ASKER

for (int i = 0 ; i < strings.length ; i++) {
    Character firstChar = strings[i].charAt(0) ;
    Integer match = map.get(firstChar) ;

    if (match == null) {
       // This is the first time we've seen this first letter
      map.put(firstChar, i) ;
    } else {
      // We've seen this same first letter before so swap the two entries
      String swap = strings[i] ;
      strings[i] = strings[match] ;
      strings[match] = swap ;

      // And they say once you've done a swap you can't swap
      // again so remove it from the map.
      map.remove(firstChar) ;
    }
  }
  
  return strings;


FOR 3RD ITERAtion where i=2 ie ax
map.get(a) is null so if condition match so put map with a, i ie a,2

for 4th iteration for i=3 ie ay firstChar is and map.get(a) is 2 not null so go to else condition

  String swap = strings[i] ;
      strings[i] = strings[match] ;
      strings[match] = swap ;
here
String swap is strings[3] ie ay then 
strings[3] assign with strings[match]ie strings[2] which is ax then
strings[match] ie strings[2] assign with swap which is ay

so finally strings[2] has swapped ay and strings[3] has swapped ax

Open in new window

Avatar of gudii9

ASKER

public String[] firstSwap(String[] strings) {
  // The map is from the first character in the string to its position in the array.
  Map<Character, Integer> map = new HashMap<>() ;
  
  for (int i = 0 ; i < strings.length ; i++) {
    Character firstChar = strings[i].charAt(0);
    Integer match = map.get(firstChar);

    if ((match == null)) {
       // This is the first time we've seen this first letter
      map.put(firstChar, i);
    } else if (match != -1) {
      // We've seen this same first letter and havent swapped yet, so swap the two entries
      String swap = strings[i];
      strings[i] = strings[match];
      strings[match] = swap;

      // And they say once you've done a swap you can't swap
      // again so mark as disabled in the map.
      map.put(firstChar, -1) ;
    }
  }
  
  return strings;
}

Open in new window

how above firstSwap code different from this allSwap solution?
how map.remove(firstChar)  different from
 map.put(firstChar, -1) ;