We help IT Professionals succeed at work.

string at particular index

419 Views
Last Modified: 2014-12-08
Hi

I was trying below example

http://codingbat.com/prob/p121596

I was not sure how to proceed on this. I wrote some dummy code as below

How to fix and improve the my code

public String altPairs(String str) {
for(int i=0;i<str.length();i++)
String str2=(str.substring(i,i+1)+str.substring(i+4,i+5));
  return str2;
}

Open in new window

Comment
Watch Question

CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
CERTIFIED EXPERT
Top Expert 2013
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
You have defined the str2 variable inside the for() scope. It needs to be defined outside of the scope:

Open in new window

i got it.
str2+=str.substring(i,i+2<=str.length()?i+2:i+1);

Open in new window

what is the meaning of above code

You need to go through the string in jumps of 4.

So the loop will be something like "i += 4" for the step.

please elaborate on this
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
the loop starts with i=0
after executing i += 4, i will be 4
after executing i += 4 again,  i will be 8

Author

Commented:

Given a string, return a string made of the chars at indexes 0,1, 4,5, 8,9 ... so "kittens" yields "kien".

altPairs("kitten") → "kien"
altPairs("Chocolate") → "Chole"
altPairs("CodingHorror") → "Congrr"

But the challenge statement as above did not mention about jumps of 4 right. can you please advise

String str2="";
for(int i=0;i<str.length();i+=4)
{
  str2+=str.substring(i,i+2<=str.length()?i+2:i+1);
}
return str2;

Open in new window


in the above working code i see jumps of 4 but not sure what is happening in below line
str2+=str.substring(i,i+2<=str.length()?i+2:i+1);
which i can translate as below more understandable to me
str2= str2+str.substring(i,i+2<=str.length()?i+2:i+1);

not clear what is being passed to substring method above as below

i,i+2<=str.length()?i+2:i+1
please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
Would it have been easier to understand if it had been
i,Math.min(str.length(),i+2)
?
CERTIFIED EXPERT
Top Expert 2013

Commented:
The operator ?: is called a ternary operator. It is a shortcut to write something in one line. Without this operator you would write:
// str2+=str.substring(i,i+2<=str.length()?i+2:i+1); is equivalent to
if(i+2<=str.length())
  str2+=str.substring(i,i+2);
else
  str2+=str.substring(i,i+1);

Open in new window

Author

Commented:
str2+=str.substring(i,i+1);
i do not see i,i+1 in below statement
str2+=str.substring(i,i+2<=str.length()?i+2:i+1); is equivalent to
Please advise
CERTIFIED EXPERT

Commented:
I think the use of a tenary operator is just confusing things here.

Since this question seems to be getting more tangled rather than less, I'm going to repost the code I posted at the very top of this question and make the one small edit:

     String str2=str.substring(i,i+2);
=>
     String str2=str.substring(i,end);

that was required to have it solve the problem.

It relies on knowing that Math.min here:
     int end = Math.min(i+2, len) ;

puts the smaller of "i+2" and "len" into the variable end.

Is this clearer?

public String altPairs(String str) {
  int len = str.length() ;
  StringBuilder result = new StringBuilder() ;

  for (int i = 0 ; i < len ; i += 4) {
     int end = Math.min(i+2, len) ;
     String str2=str.substring(i,end);
     result.append(str2) ;
  }
  
  return result.toString() ;
}

Open in new window

Author

Commented:
0,1, 4,5, 8,9


Given a string, return a string made of the chars at indexes 0,1, 4,5, 8,9 ... so "kittens" yields "kien".

altPairs("kitten") → "kien"
altPairs("Chocolate") → "Chole"
altPairs("CodingHorror") → "Congrr"

in the chalenge above numbers given right. Is it is like fibonacci series?
i do not see any pattern. what comes after 9?

I wonder why we are incrementing by 4
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
It is true that there are an infinite number of different series that start 0,1, 4,5, 8,9 ...,
so the problem is technically underspecified, most people seem to be interpreting it as
0,1,
4,5,
8,9,
8+4,8+4+1,
12+4,12+4+1,
16+4,16+4+1,
20+4,20+4+1,
24+4,24+4+1,
...
(and there are still an infinite number of different ways to extend that pattern, but none of the test strings are that long, so it doesn't really matter)
CERTIFIED EXPERT

Commented:
I wonder why we are incrementing by 4

We're incrementing by 4 because that's what the pattern suggested we needed to do.  It's not the fibonacci series.  The sequence is just the pair (0,1) and then adding 4 to generate the next pair (4,5) and 4 to get the next pair (8,9) etc.

So overall we get (0,1,4,5,8,9,...)

Author

Commented:
The sequence is just the pair (0,1) and then adding 4 to generate the next pair (4,5) and 4 to get the next pair (8,9) etc.

now i understand the pattern

for (int i = 0 ; i < len ; i += 4) {
     int end = Math.min(i+2, len) ;
     String str2=str.substring(i,end);

what are we doing in above 4 lines after incrementing by 4 to get the next set of 2 numbers? why we are getting substring i till end(excluding end ofcourse) all the way?
please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
when i==0, we want str.substring(0,2), unless Math.min(i+2, len)  < 2, in which case we want  str.substring(0,len),

Author

Commented:
unless Math.min(i+2, len)  < 2
this never happens right even if you take i as 0
2<2 can never happen. please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
len < i+2 can happen

Author

Commented:
how and when
2<=2 can happen but not 2<2 right?
please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
2<=2 is always true
2<2  is never true

Author

Commented:
correct.

public String altPairs(String str) {
  int len = str.length() ;
  StringBuilder result = new StringBuilder() ;

  for (int i = 0 ; i < len ; i += 4) {
  // int end = Math.min(i+2, len) ;
  int end=len;
     String str2=str.substring(i,end);
     result.append(str2) ;
  }
  
  return result.toString() ;
}

Open in new window

when i commented above Math.min function line i am failing in all test cases where length is more than 2
Expected	Run		
altPairs("kitten") → "kien"	"kittenen"	X	    
altPairs("Chocolate") → "Chole"	"Chocolateolatee"	X	    
altPairs("CodingHorror") → "Congrr"	"CodingHorrorngHorrorrror"	X	    
altPairs("yak") → "ya"	"yak"	X	    
altPairs("ya") → "ya"	"ya"	OK	    
altPairs("y") → "y"	"y"	OK	    
altPairs("") → ""	""	OK	    
altPairs("ThisThatTheOther") → "ThThThth"	"ThisThatTheOtherThatTheOtherTheOtherther"	X	   

Open in new window


i did not completely get this Math.min function use here.
Please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:

Author

Commented:
0 length string("") take 2 as end..so appends 0,1 index characters which are"" and ""
1 length string("y") take 2 as end..so appends 0,1 index characters which are"y" and ""
2 length string("ya" take 2 as end..so appends 0,1 index characters which are"y" and "a"
3 length string("yak") take 2 as end..so appends 0,1 index characters which are"y" and "a" in first iteration(when i=0) and appends k in second iteration(when i=1)
6 length string("kitten") 2 as end....so appends 0,1 index characters which are"k" and "i" in first iteration(when i=0) and appends t,t in second iteration(when i=1) and  appends e,n in second iteration(when i=2)

but we are moving i by 4 after each iteration right?? please advise
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
it all make better sense now.
public String altPairs(String str) {
  int len = str.length() ;
  StringBuilder result = new StringBuilder() ;

  for (int i = 0 ; i < len-1 ; i += 4) {
  int end = Math.min(i+2, len) ;
  //int end=len;
     String str2=str.substring(i,end);
     result.append(str2) ;
  }
  
  return result.toString() ;
}

Open in new window


when i wrote as above by doing -1 i got couple of tests failied
Expected	Run		
altPairs("kitten") → "kien"	"kien"	OK	    
altPairs("Chocolate") → "Chole"	"Chol"	X	    
altPairs("CodingHorror") → "Congrr"	"Congrr"	OK	    
altPairs("yak") → "ya"	"ya"	OK	    
altPairs("ya") → "ya"	"ya"	OK	    
altPairs("y") → "y"	""	X	    
altPairs("") → ""	""	OK	    
altPairs("ThisThatTheOther") → "ThThThth"	"ThThThth"	OK	

Open in new window

i wonder why they failed esp.
altPairs("Chocolate") → "Chole"      "Chol"      X
CERTIFIED EXPERT

Commented:
for (int i = 0 ; i < len-1 ; i += 4)

Is causing the loop to stop too soon (the -1 makes it stop 1 before the last character).

You can either have:
for (int i = 0 ; i < len ; i += 4)
or
for (int i = 0 ; i <= len-1 ; i += 4)

Both are equivalent.  So if you prefer to think about "len-1" you need to use "<=".

The reason most people write:
for (int i = 0 ; i < len ; i += 4)
is because the loop starts from 0, not 1.

So
for (int i = 0 ; i < 10 ; i++)
means to loop 10 times (0,1,2,3,4,5,6,7,8,9).  So it's easier to read when the "10" is the limit or "len" is the limit in this loop.

For that to work, we use i < 10 or i < len.

Does that make sense?

Doug

Author

Commented:
yes.

I wonder why it failed for below test case while using i < len-1
altPairs("Chocolate") → "Chole"      "Chol"      X
CERTIFIED EXPERT

Commented:
"Chocolate" is a string of length 9.  So len - 1 is 8.

This means the loop becomes:
for (i = 0 ; i < 8 ; i += 4)
which means we get (0,4) as the values for i instead of (0,4,8) if the test was i < len.

So we miss the last group of characters - the trailing "e" in this case.

Doug

Author

Commented:
altPairs("y") → "y"	""	X

Open in new window


sorry i meant to ask why it failed for above test case. please advise

Author

Commented:
int end = Math.min(i+2, len) ;

Open in new window


so basically we are getting end to feed to substring method to get next set of characters to be appeneded to string builder right?
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
"y" is a string of length 1, so len - 1 is 0, so altPairs("y") failed for the same reason as altPairs("Chocolate")

we are getting end to feed to substring method
correct
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
It can actually be useful to loop only for  i<len-1, because that guarantees that within the loop, str.substring(i,i+2) will not be out of bounds, which makes it unnecessary to repeatedly guard for that condition inside the loop body.
After the loop is done, we can then do a single check to see if we need to append one more character in the case where we stopped to soon to get the final length 1 piece of str.substring(i,len):

public String altPairs(String str) {
  int len = str.length() ;
  StringBuilder result = new StringBuilder() ;
  int i;
  for ( i = 0 ; i < len-1 ; i += 4) {
     result.append(str.substring(i,i+2)) ;
  }
  if( i==len-1 ){
     result.append(str.substring(i)) ;
  }
  return result.toString() ;
}

Author

Commented:
I see above solution more clear.
altPairs("") → ""      ""      OK       
will not go to if loop of above solution right.

only when len is one like "y" string it goes to aboe if loop for rest of scenarios just go to for loop and appends the string using substring method and returns as result.toString right?

Author

Commented:
altPairs("") → ""	""	OK	

Open in new window


how it works for above case
i<len-1(here len-1 becomes -1 for i=0 right)
Please advjes
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
for ( i = 0 ; i < len-1 ; i += 4) does not go into the loop body when len==0 or len==1
for ( i = 0 ; i < len ; i += 4) does not go into the loop body when len==0 but does go into the loop body when len==1

Author

Commented:
correct
public String altPairs(String str) {
  int len = str.length() ;
  StringBuilder result = new StringBuilder() ;
  int i;
  for ( i = 0 ; i < len-1 ; i += 4) {
     result.append(str.substring(i,i+2)) ;
  }
  if( i==len-1 ){
     result.append(str.substring(i)) ;
  }
  return result.toString() ;
}

for ( i = 0 ; i < len-1 ; i += 4) does not go into the loop body when len==0 or len==1

How above solution is working then for len==0 and len==2. please advise

Author

Commented:
when len==1 i can visualize it going into if loop and eppending as below
 if( i==len-1 ){
     result.append(str.substring(i)) ;
  }

but if len==0 how solution passed the test case(for string like""). please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
if len==0, the solution of http#a40454432 reduces to

public String altPairs(String str) {
  int len = str.length() ;
  StringBuilder result = new StringBuilder() ;
  int i;
  // don't execute code in for loop body, don't execute code in if body
  return result.toString() ;
}

Author

Commented:
if len==0, the solution of http#a40454432 reduces to
i could not see above mentioned url--a40454432

https://www.experts-exchange.com/Programming/Languages/Java/Q_40454432.html

i tied this also
https://www.experts-exchange.com/Programming/Languages/Java/Q_a40454432.html
is it is spearate question or separate comment on this question?

Author

Commented:
ozo2014-11-19 at 23:49:00ID: 40454432

i see without a

Author

Commented:
if len==0, the solution of http#a40454432 reduces to

so the code supposed to be as below
public String altPairs(String str) {
  int len = str.length() ;
  StringBuilder result = new StringBuilder() ;
  int i;
  // don't execute code in for loop body, don't execute code in if body
  return result.toString() ;
}

Open in new window

should not be as below? please advise
public String altPairs(String str) {
  int len = str.length() ;
  StringBuilder result = new StringBuilder() ;
  int i;
  for ( i = 0 ; i < len-1 ; i += 4) {
     result.append(str.substring(i,i+2)) ;
  }
  if( i==len-1 ){
     result.append(str.substring(i)) ;
  }
  return result.toString() ;
}

Open in new window

Author

Commented:
I see if the len==0 then it directly goes to

return result.toString() ; without going to for and if loop.

Please advise if my understanding is correct?
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
if the len==0 then it directly goes to

return result.toString() ;
That's correct


http#a40454432
should have been
http:#a40454432

Author

Commented:
// str2+=str.substring(i,i+2<=str.length()?i+2:i+1); is equivalent to
if(i+2<=str.length())
  str2+=str.substring(i,i+2);
else
  str2+=str.substring(i,i+1)

Open in new window


i am still trying to understand how these two are  equivalent.
substring second argument is
i+2<=str.length()?i+2:i+1
which means
if i+2<=str.length() is true take i+2 //when this case happen?
if i+2<=str.length() is false take i+1 as value.//when this case happen?
please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
when i+2<=str.length() is true,  i+2<=str.length()?i+2:i+1 is i+2
when i+2<=str.length() is false, i+2<=str.length()?i+2:i+1 is i+1

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html

Author

Commented:
altPairs("kitten") → "kien"	"kien"	OK

Open in new window

for above example str.length is 6 right
for the first iteration i=0

so
str2+=str.substring(i,i+2<=str.length()?i+2:i+1);

Open in new window

i+2<=str.length()?i+2:i+1 becomes 2<=6 since true takes i+2 which is 2
so it should print 0,2 indexed characters as first set right before incrementing by 4 for next set.

But we do not want 0,2 but instead we want 0,1.

Please correct where i am thinking wrong. The test cases are passing so my understanding is wrong above some where. please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
"kitten".substring(0,2) is "ki", which we want
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
One way to visualize it could be to think of the index numbers as being between the characters in the string, and the substring character being between the selected index numbers
 _ _
 k i t t e n
| ^ | ^ ^ ^ ^
0 1 2 3 4 5 6

Open in new window

Author

Commented:
"kitten".substring(0,2) is "ki", which we want

Given a string, return a string made of the chars at indexes 0,1, 4,5, 8,9 ... so "kittens" yields "kien".

altPairs("kitten") → "kien"
altPairs("Chocolate") → "Chole"
altPairs("CodingHorror") → "Congrr"

challenge says 0,1 then 4,5 then 8,9 right

Author

Commented:
Oh well i see substring end is excluded right unlike start index.
Ok i got it now
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
challenge says at indexes 0,1
challenge does not say substring(0,1)

Author

Commented:
altPairs("y") → "y"      "y"      OK         
altPairs("") → ""      ""      OK      

these are only two scenarios where false returns
i+2<=str.length()?i+2:i+1

Open in new window


so  i+1 is returned.
so the substring becomes

altPairs("y") → "y"      "y"      OK        ===>substring(0,1)  --->so give back y
altPairs("") → ""               ====>substring(0,1) so gives back ""

But to begin with how we know to compare with i+2 as below(not i or i+1)
i+2<=
please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
altPairs("") makes len==0
so whether we loop for ( i = 0 ; i < len-1 ; i += 4)
or for ( i = 0 ; i < len ; i += 4)
the loop condition starts out false, so we don't even enter the loop body

altPairs("y") makes str.length()==1
so i+2<str.length() is false, which means i+2<=str.length()?i+2:i+1 is i+1

Author

Commented:
altPairs("CodingHorror") → "Congrr"	"Congrr"	OK	

Open in new window


how we got Congrr??


substring second argument is
i+2<=str.length()?i+2:i+1
which means
if i+2<=str.length() is true take i+2

so we get substring(0,2) which is "Co" in the first iteration


then i incremented by 4 so 0 becomes 4
6<=12 true so take i+2
so we get substring(4,6) which is "ng" in the second iteration


then i incremented by 4 so 4 becomes 8
8<=12 true so take i+2
so we get substring(8,10) which is "rr" in the second iteration

so i+1 scenario only comes for "y"(1 character strings)
if empty string wil not even go inside the loop.

Please advise if my understanding is correct?
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
i+1 scenario also comes for "Chocolate"

Author

Commented:
i+1 scenario also comes for "Chocolate"
oh. When does it come for Chocolate. Please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
When i==8

Author

Commented:
for(int i=0;i<str.length();i+=4)
the loop condition starts out false, so we don't even enter the loop body when i=8 right?
please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
"Chocolate".length() ==9
 8<9 is true

Author

Commented:
public class Test33 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
    //altPairs("chocolate");
    System.out.println("value is-->"+altPairs("chocolate"));
	}

	public static String altPairs(String str) {
	String str2="";
	for(int i=0;i<str.length();i+=4)
	{
	  str2+=str.substring(i,i+2<=str.length()?i+2:i+1);
	}
	return str2; 
	}
}

Open in new window

i got output
value is-->chole


how we got chole??


substring second argument is
i+2<=str.length()?i+2:i+1
which means
if i+2<=str.length() is true take i+2

so we get substring(0,2) which is "ch" in the first iteration


then i incremented by 4 so 0 becomes 4
6<=8 true so take i+2
so we get substring(4,6) which is "ol" in the second iteration

//chocolate
then i incremented by 4 so 4 becomes 8
8<=8 true so take i+2
so we get substring(8,10) which is "e?" in the third iteration

so i+1 is not coming right.

Please advise where i am missing
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
8+2<="Chocolate".length() is not true

Author

Commented:
i got output
value is-->chole


how we got chole??


substring second argument is
i+2<=str.length()?i+2:i+1
which means
if i+2<=str.length() is true take i+2 (since2<=8)

so we get substring(0,2) which is "ch" in the first iteration


then i incremented by 4 so 0 becomes 4
6<=8 true so take i+2
so we get substring(4,6) which is "ol" in the second iteration

//chocolate
then i incremented by 4 so 4 becomes 8
10<=8 false so take i+1
so we get substring(8,9) which is "e" in the third iteration

so i+1 is  coming right.

is my understanding above is correct now right? please advise
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
"Chocolate".length() is 9, not 8

Author

Commented:
i got output
value is-->chole


how we got chole??


substring second argument is
i+2<=str.length()?i+2:i+1
which means
if i+2<=str.length() is true take i+2 (since2<=9)

so we get substring(0,2) which is "ch" in the first iteration


then i incremented by 4 so 0 becomes 4
6<=9 true so take i+2
so we get substring(4,6) which is "ol" in the second iteration

//chocolate
then i incremented by 4 so 4 becomes 8
10<=9 false so take i+1
so we get substring(8,9) which is "e" in the third iteration
so i+1 is  coming right.
my above understanding is correct right? please advise

Author

Commented:
Please advise as i corrected my above post as highlighted place
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
yes

Author

Commented:
thank you

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.