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

asked on

firstswap to swap the characters

Hi,

http://codingbat.com/prob/p150113

I am trying to solve above 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. A particular first char can only cause 1 swap, so once a char has caused a swap, its later swaps are disabled. Using a map, this can be solved making just one pass over the array. More difficult than it looks.


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

Open in new window



How to approach this challenge. I was not clear on above description either. 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
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 dpearson
dpearson

Ah yes - gotcha.  *Almost* the same :)

Doug
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.

i was not clear on description

if string matches earlier string means whole string or some characters? what it means swapped when match? how many times we can swap.

please advise
The match is just "their first chars are the same".  So just the first character.

And then to swap means if we had strings:

A, B, C, D

and we swapped B and D then we'd have

A, D, C, B
sample input and outputs

firstSwap(["ab", "ac"]) → ["ac", "ab"]
firstSwap(["ax", "bx", "cx", "cy", "by", "ay", "aaa", "azz"]) → ["ay", "by", "cy", "cx", "bx", "ax", "aaa", "azz"]
firstSwap(["ax", "bx", "ay", "by", "ai", "aj", "bx", "by"]) → ["ay", "by", "ax", "bx", "ai", "aj", "bx", "by"]
firstSwap(["ax", "bx", "cx", "ay", "cy", "aaa", "abb"]) → ["ay", "bx", "cy", "ax", "cx", "aaa", "abb"]
firstSwap(["easy", "does", "it", "every", "ice", "eaten"]) → ["every", "does", "ice", "easy", "it", "eaten"]
firstSwap(["list", "of", "words", "swims", "over", "lily", "water", "wait"]) → ["lily", "over", "water", "swims", "of", "list", "words", "wait"]
firstSwap(["4", "8", "15", "16", "23", "42"]) → ["42", "8", "16", "15", "23", "4"]
firstSwap(["aaa"]) → ["aaa"]
firstSwap([]) → []
firstSwap(["a", "b", "c", "xx", "yy", "zz"]) → ["a", "b", "c", "xx", "yy", "zz"]

Open in new window

Avatar of gudii9

ASKER

firstSwap(["ab", "ac"]) → ["ac", "ab"]

since a match in both above 2 string swap 2nd character to get ac, ab (instead of ab, ac) and with other inputs?
is my understanding is correct?
how this firstswap different from other challenge allswap?
Avatar of gudii9

ASKER

can we do without using map?
don't we need to use 2 for loops for this

I started some thing like below but not able to proceed

public String[] firstSwap(String[] strings) {
  for(int i=0;i<strings.length;i++){
    
    
    for(int j;j<strings.length;j++){
      if(strings.indexOf(0)
    }
    
  }
}

Open in new window


please advise
this one swaps only first occurrences, not all

firstSwap(["ax", "bx", "cx", "ay", "cy", "aaa", "abb"]) → ["ay", "bx", "cy", "ax", "cx", "aaa", "abb"]

allSwap(["ax", "bx", "cx", "ay", "cy", "aaa", "abb"]) → ["ay", "bx", "cy", "ax", "cx", "abb", "aaa"]

Open in new window


here, "ax" and "ay" are swapped but not "aaa" or "abb"

also, in the page you provided it says
Using a map, this can be solved making just one pass over the array.

this is one pass solution which is efficient than 2 loops inside...
Avatar of gudii9

ASKER


this is one pass solution which is efficient than 2 loops inside.

can you show with 2 for loops then i can see map example
so do you want me write multiple solutions to a given problem and then compare :)

it will be something like this:

public String[] firstSwap(String[] strings) {
  Map<Character, Integer> map = new HashMap<>();
  
  for (int i=0; i<strings.length-1; i++){
    Character firstChar = strings[i].charAt(0);
    if (!map.containsKey(firstChar)){
      for (int j=i+1; j<strings.length; j++)  {
        if (firstChar==strings[j].charAt(0)){
          map.put(firstChar, 1);
          String t = strings[i];
          strings[i] = strings[j];
          strings[j] = t;
          break;
        }
      }
    }
  }

  return strings;
}

Open in new window


number of iteration in this code will be

i=0 > j=1..n > total n-1
i=1 > j=2..n > total n-2
...
i=n-1 > j=n..n > total 1

Open in new window


if we sum all,

(n-1) + (n-2) + (n-3) + ... + 1 = n*(n-1)/2

Open in new window


for n=6, we will have 6*5/2=15 iteration (worst case, all  items are starting with different character)...

like this one:

firstSwap(["a", "b", "c", "xx", "yy", "zz"]) → ["a", "b", "c", "xx", "yy", "zz"]

Open in new window

to test number of iterations, check this code

public String[] firstSwap(String[] strings) {
  Map<Character, Integer> map = new HashMap<>();
  int n=0;
  for (int i=0; i<strings.length-1; i++){
    Character firstChar = strings[i].charAt(0);
    if (!map.containsKey(firstChar)){
      for (int j=i+1; j<strings.length; j++)  {
        n++;
        if (firstChar==strings[j].charAt(0)){
          map.put(firstChar, 1);
          String t = strings[i];
          strings[i] = strings[j];
          strings[j] = t;
          break;
        }
      }
    }
  }
  //strings[0] = Integer.toString(n);
  return strings;
}

Open in new window


uncomment line 19 to test...

User generated image
Avatar of gudii9

ASKER

let me digest this
Avatar of gudii9

ASKER

[quote]this one swaps only first occurrences, not all

firstSwap(["ax", "bx", "cx", "ay", "cy", "aaa", "abb"]) → ["ay", "bx", "cy", "ax", "cx", "aaa", "abb"]

allSwap(["ax", "bx", "cx", "ay", "cy", "aaa", "abb"]) → ["ay", "bx", "cy", "ax", "cx", "abb", "aaa"]

Select all
 
Open in new window

here, "ax" and "ay" are swapped but not "aaa" or "abb"[/quote]

now i understood diference between first swap and all swap challenge question.

what is the difference in solution for these two challenge questions?

i was not clear on overall code flow and specifically below 3 lines




// 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;

Open in new window

Avatar of gudii9

ASKER

  map.put(firstChar, -1) ;

Open in new window

what is meaning of above line?
Avatar of gudii9

ASKER

how this firstSwap code diferent from allSwap code
public String[] allSwap(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 {
      // 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;
}

Open in new window

Avatar of gudii9

ASKER

map.remove(firstChar) ;
how above different from below
  map.put(firstChar, -1) ;
Avatar of gudii9

ASKER

i think i got it instead if removing a,0 we are making a, -1

for ab, ac, ax, ay example
once ab ac swapped to ac ab
then ax turn comes
first letter in ax a and map.get a is -1 since else condition checks if not -1 then only goes inside and swaps so ax remains as it is
simiary ay 4th iteration turn comes
first letter in ay a and map.get a is -1 since else condition checks if not -1 then only goes inside and swaps so ax remains as it is
Avatar of gudii9

ASKER

any other wqy of doing than map?

public String[] firstSwap(String[] strings) {
  Map<Character, Integer> map = new HashMap<>();
  
  for (int i=0; i<strings.length-1; i++){
    Character firstChar = strings[i].charAt(0);
    if (!map.containsKey(firstChar)){
      for (int j=i+1; j<strings.length; j++)  {
        if (firstChar==strings[j].charAt(0)){
          map.put(firstChar, 1);
          String t = strings[i];
          strings[i] = strings[j];
          strings[j] = t;
          break;
        }
      }
    }
  }

  return strings;
}

Select all
 
Open in new window

number of iteration in this code will be

i=0 > j=1..n > total n-1
i=1 > j=2..n > total n-2
...
i=n-1 > j=n..n > total 1

Open in new window

not clear on n(n-1)/2 iternations here? how that many iterations? how to count them?
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

If strings[] contains ["0", "1", "2", "3", "4"]
How many times will you execute line 8 when i=0?
i is index of array or string array element?
Avatar of gudii9

ASKER

  
  for (int i=0; i<strings.length-1; i++){
    Character firstChar = strings[i].charAt(0);
    if (!map.containsKey(firstChar)){
      for (int j=i+1; j<strings.length; j++)  {
        if (firstChar==strings[j].charAt(0)){

Open in new window


line 8 has j right not i? i am confused. please advise
i is this i  for (int i=0; i<strings.length-1; i++){
line 8 in https:#a42351839 was if (firstChar==strings[j].charAt(0)){
Avatar of gudii9

ASKER

line 8 in https:#a42351839 was if (firstChar==strings[j].charAt(0)){
for me it is showing as line 5
Avatar of gudii9

ASKER

public String[] firstSwap(String[] strings) {
  Map<Character, Integer> map = new HashMap<>();
  
  for (int i=0; i<strings.length-1; i++){
    Character firstChar = strings[i].charAt(0);

If strings[] contains ["0", "1", "2", "3", "4"]
How many times will you execute line 8 when i=0?// for i =0 we run once then increment i to 1 right?
How many times will you execute line 8 when i=1?for i =1 we run once then increment i to 2 right?same way others
How many times will you execute line 8 when i=2?
How many times will you execute line 8 when i=3?
How many times will you execute line 8 when i=4?
What is the total?//5 times?

Open in new window

for me, https://www.experts-exchange.com/viewCodeSnippet.jsp?codeSnippetId=20-42351839-1 displays as

 1: public String[] firstSwap(String[] strings) {
 2:   Map<Character, Integer> map = new HashMap<>();
 3:
 4:   for (int i=0; i<strings.length-1; i++){
 5:     Character firstChar = strings[i].charAt(0);
 6:     if (!map.containsKey(firstChar)
 7:       for (int j=i+1; j<strings.length; j++) {
 8:         if (firstChar==strings[j].charAt(0)){
 9:           map.put(firstChar, 1);
10:           String t = strings[i];
11:           strings[i] = strings[j];
12:           strings[j] = t;
13:           break;
14:         }
15:       }
16:     }
17:   }
18:
19:   return strings;
20: }
21:
22: Select all
23:
24: Open in new window
25:
26: number of iteration in this code will be
27:
28: i=0 > j=1..n > total n-1
29: i=1 > j=2..n > total n-2
30: ...
31: i=n-1 > j=n..n > total 1

Open in new window

Avatar of gudii9

ASKER

public String[] firstSwap(String[] strings) {
 2:   Map<Character, Integer> map = new HashMap<>();
 3:
 4:   for (int i=0; i<strings.length-1; i++){
 5:     Character firstChar = strings[i].charAt(0);
 6:     if (!map.containsKey(firstChar)
 7:       for (int j=i+1; j<strings.length; j++) {
 8:         if (firstChar==strings[j].charAt(0)){

Open in new window


line 8 is if condition within iner for loop whose counter is j ??
Yes. How many times does that condition get tested?
Avatar of gudii9

ASKER

i*j times? just guessing
Avatar of gudii9

ASKER

for i=0, j goes on and on until strings.length
for (int i=0; i<strings.length-1; i++){
 5:     Character firstChar = strings[i].charAt(0);
 6:     if (!map.containsKey(firstChar)
 7:       for (int j=i+1; j<strings.length; j++) {
 8:         if (firstChar==strings[j].charAt(0)){

then i=1 again j goes on and on until strings.length

until i<strings.length again j goes on and on until strings.length

Open in new window

Think we covered this pretty well :)