string characters first three multiple times

Hi,

I was trying below challenge
http://codingbat.com/prob/p136351


I wrote as below
public String front3(String str) {

if(str.length()==3){
return str+str+str;

}

if(str.length()>3){
String str2=str.charAt(0)+str.charAt(1)+str.charAt(2);
return str2+str2+str2;

}

}

I get error as below


Error:      String str2=str.charAt(0)+str.charAt(1)+str.charAt(2);
             ^^^^
Type mismatch: cannot convert from int to String

what is the effective way to solve this challenge. Please advise. Thanks in advance
LVL 7
gudii9Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

krakatoaCommented:
To make a String from a bunch of chars, you'd have to do something like :

String str = "hello";
String str2 = new String(new char[]{str.charAt(0),str.charAt(1),str.charAt(2)});

Open in new window

0
gudii9Author Commented:
I changed as below
public String front3(String str) {

if(str.length()==3){
return str+str+str;

}

if(str.length()>3){
String str2=new String(new char[]{str.charAt(0),str.charAt(1),str.charAt(2)});
return str2;

}

}

Open in new window


i still get error as


Compile problems:


Error:      public String front3(String str) {
                    ^^^^^^^^^^^^^^^^^^
This method must return a result of type String

Possible problem: the if-statement structure may theoretically
allow a run to reach the end of the method without calling return.
Consider adding a last line in the method return some_value;
so a value is always returned.


Please advise
0
krakatoaCommented:
What is the String that you are passing to the method?
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

ozoCommented:
there may be another possibility besides ==3 and >3
0
rrzCommented:
This passes the tests.
public String front3(String str) {
  if(str.length()<=3){
      return str+str+str;
  }
   else{
      String str2 = "" + str.charAt(0) + str.charAt(1) + str.charAt(2);
      return str2+str2+str2;
   }

}

Open in new window

I just used the empty String ("") to force Java to make a String out of the concatenation of chars.
0
dpearsonCommented:
Here's another way to solve it that is perhaps a little cleaner?

Math.min(3,str.length()) will be either 3 or the length of the string - whichever is smaller.

public String front3(String str) {
  String front = str.substring(0,Math.min(3,str.length())) ;
  return front + front + front ;
}

Open in new window


Another general rule for writing clean code is to avoid "if () ... else ..." whenever possible, because it makes the flow of the code a little harder to understand.

Doug
0
CEHJCommented:
More verbose but avoiding string concatenation:

    public String front3(String str) {
        String result = null;
        int frontLength = Math.min(str.length(), 3);
        StringBuilder sb = new StringBuilder(frontLength * 3);

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < frontLength; j++) {
                sb.append(str.charAt(j));
            }
        }

        result = sb.toString();

        return result;
    }

Open in new window

0
krakatoaCommented:
You could always squeeze a bit more abstraction out of the situation, by this, and again pass some burden back to Java :

String s = "hello";
final int FRONT = Math.min(s.length(),3);
String[] sA = new String[FRONT];

Arrays.fill(sA,s.substring(0,sA.length));

for(int r=0;r<sA.length;r++){System.out.print(sA[r]);}//*

Open in new window


(Meaning you'd 'return' sA, for later decomposition*).
0
ozoCommented:
avoid "if () ... else ..." whenever possible
To avoid "if () ... else ..." is always possible, but what you may end up using instead
could make the flow of the code harder to understand.

To always avoid "if () ... else ..." suggests the sort of general rule up with which I will not put.
0
rrzCommented:
avoid "if () ... else ..." whenever possible
I don't agree. It is perfectly acceptable when the scope of the else is clear. In this case, the length of the String is <=3 or its not.
0
ozoCommented:
So I suspect that dpearson didn't really mean "whenever possible"
(or perhaps didn't really mean "if () ... else ..."?)
"when not called for" would be something I'd agree with, but it would also seem unnecessary to say.
0
krakatoaCommented:
If I had to take only one tool with me to my programmers' desert island, it'd be the 'if' statement. ;)
0
CEHJCommented:
(or perhaps didn't really mean "if () ... else ..."?)

I suspect he meant 'if () ... if() ...' etc.
0
krakatoaCommented:
Hmm . . . that sounds a bit iffy.
0
dpearsonCommented:
Hey guys,

I did mean that you should try to avoid conditionals (if ... ) when an equivalent exists that is a reasonable alternative.

To go back to the original example this code is perfectly clear and correct:

 
if(str.length()<=3){
      return str+str+str;
  }
   else{
      String str2 = "" + str.charAt(0) + str.charAt(1) + str.charAt(2);
      return str2+str2+str2;
   }

Open in new window


However, in my opinion (and it's just that - an opinion), this code should be preferred:

 String front = str.substring(0,Math.min(3,str.length())) ;
  return front + front + front ;

Open in new window


because it removes the branching and is a reasonable solution.  (If the alternative with no branching was super complex for some reason, then I wouldn't advocate doing this).

Let me try to explain why I think this is better.

1) Removing conditionals means the flow of control is clearer to a human reader.
    The person mentally executing the code doesn't need to reason about which branch they are in and what statements will be executed in each branch.  You might say "ha - it's easy to see what this method does" but what happens over time as more code gets added here?  Imagine the requirements change and now when the string length is 1 we should return just one copy of the string, the code starts to become pretty complex (at least to my eye):
 
if(str.length()<=3){
      if (str.length() == 1) {
         return str ;
      } else {  
         return str+str+str;
      }
  }
   else{
      String str2 = "" + str.charAt(0) + str.charAt(1) + str.charAt(2);
      return str2+str2+str2;
   }

Open in new window


e.g. it's getting harder to tell what the 2nd else refers to, especially if the indentation gets off:
 
if(str.length()<=3){
     if (str.length() == 1) {
            return str ;
         } else {  
            return str+str+str;
         }
      }
      else{
         String str2 = "" + str.charAt(0) + str.charAt(1) + str.charAt(2);
          return str2+str2+str2;
      }

Open in new window


2) Removing conditionals makes code coverage and testing simpler.
    With the first version, there are 2 completely different paths through this method.  One branch could work perfectly and the other could be completely wrong.  If you called it in such a way that it only exercises one branch it's easy to not realize that the alternative code has not been executed and may be wrong.  Of course the same could be true for a method without a conditional branch - but it's less likely because more of the code is common and is executed every time through the method.

3) Conditionals are slower to execute.
    This is relatively small point, but certainly something we should be aware of.  If you have a branch, then down at the level of the processor it prevents certain optimizations where the CPU can fetch data in advance that it knows it will need, because it's less clear which side of a branch will execute.  Dangerous to take this point too far for a trivial example (comments about premature optimization are completely appropriate), but again as a rule of thumb, it's a plus for not branching.  (In this example the implementation of Math.min() might include a branch in its implementation, negating this benefit, but I'm talking more generally here).

4) Maintaining code with branches is more difficult than maintaining code without branches.
   This relates to issue #2, but when you modify a method that has a branch you essentially need to make sure that both sides of the branch are modified correctly.

E.g. It's quite possible to imagine somebody changing the requirements for this method to only have it return 2 copies of the original string and making this change:

if(str.length()<=3){
      return str+str+str;
  }
   else{
      String str2 = "" + str.charAt(0) + str.charAt(1) + str.charAt(2);
      return str2+str2;
    }

Open in new window


which is wrong because only one branch is edited but would produce the correct result for many inputs.  Of course there's nothing to stop somebody from correctly editing the method, it's just a bit easier for mistakes to slip in, because there's 2 parts to the method that are essentially doing the same thing and so both need to be edited to apply a change.

As I say, this is just an opinion.  And I'm not trying to say the original code was wrong - just trying to help the OP learn good software habits.  I've got 15+ years professional experience shipping commercial software and it's a guideline that I've found worth adopting and a practice that I recommend others try to follow - when it's reasonable, which I think it is here :)

Doug
0
ozoCommented:
Not all of those points are specific to "if () ... else ..." per se, but "when it's reasonable" does seem a better guideline to me than "whenever possible"
0
rrzCommented:
Doug,  you have convinced me.  I agree with you. Thank you for sharing.
0
ozoCommented:
Pedagogically, there seem to be at least two goals in play here:
To show the question author how to use the language elements they asked about,
and
To show the question author other language elements appropriate to solving the problem at hand.

Ultimately, one would want knowledge of both to be able to select the best language elements for solving a given problem and to use those language elements effectively.

In this case, the question author seems to have had some issues with int vs string types, as well as issues with if () ... [I don't actually see an else ... in the question author's code, and it wasn't obvious how much of the comment in http:#a40347274 might have related specifically to else ...]
So I don't think it was inappropriate to try to address those issues until they were resolved.
(are they? I haven't heard from the author since http:#a40346818)

Philosophically, when there's more than one way to do it, one's choice may be influenced by what other variant problems one perceives to be similar to the given problem, or by what one perceives to be the general problem which the given problem is an instance of.
Some variants mentioned here have been "when the string length is 1 we should return just one copy of the string" or "return 2 copies of the original string"
Code was also given for a variant not explicitly mentioned that returns 3 copies when the string length is 3 or less, and 2 copies otherwise.
There is no definitive way to determine which of those, or other possible variants, represents a better general class of programs that the given program can be considered a specific instance of, although with experience, one often gains a sense of what kinds of changes may be more useful.
(experience with different types of applications may also lead to different expectations for the kinds of changes that could be useful)

Math.min and substring are among the language elements of Java that can be useful for a programmer to know.
So are if () ... and if () ... else ...
From one point of view, (http:#a40347696) the latter might be considered more fundamental, as a beginning programmer might be able to manage without the use of Math.min and substring  better than without the use of the 'if' statement.
(although, in Java, it is always possible to avoid if () ... else ...)

Perhaps I can propose a compromise?

public String front3(String str) {
  if( str.length()>3 ){
     str=str.substring(0,3);
   }
   return str + str + str ;
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gudii9Author Commented:
public String front3(String str) {

if(str.length()==3){
return str+str+str;

}

if(str.length()>3){
String str2=str.charAt(0)+str.charAt(1)+str.charAt(2);
return str2+str2+str2;

}

}

Open in new window



why i got error as in original post


if i write like below

public String front3(String str) {

if(str.length()==3){
return str+str+str;

}

if(str.length()>3){
String str2=str.charAt(0)+str.charAt(1)+str.charAt(2);
return str2+str2+str2;

}
return null;
}

Open in new window


But not sure why to add null at the method last line since method expects String. That seems not correct approach of  returning null.

What heppens if i pass illegal out of range 'n' who handle it. please advise
0
rrzCommented:
What heppens if i pass illegal out of range 'n' who handle it.
Are you talking about your other question at
http://www.experts-exchange.com/Programming/Languages/Java/J2EE/Q_28525201.html   
?  It doesn't apply here.  
But not sure why to add null at the method last line since method expects String. That seems not correct approach of  returning null.
Returning null is ok.  The uninitialized state of String is null. It might be better to return a String such as "Error".
why i got error as in original post
The compiler insists that you return a value in every path through your code. If the two conditionals fail, then there would be a third path and you have to return a value.
0
krakatoaCommented:
My thought was rather that the compiler didn't like you trying to make a String from a series of chars. You have to use a char[] - a char array - or else use the other suggestion which was to concatenate an empty String with chars.

Or are you once again referring to something else completely?

By the way -  what String did you pass into the method when it failed here.
0
gudii9Author Commented:
public String front3(String str) {
  if(str.length()<=3){
      return str+str+str;
  }
   else{
      String str2 = "" + str.charAt(0) + str.charAt(1) + str.charAt(2);
      return str2+str2+str2;
   }

}

I just used the empty String ("") to force Java to make a String out of the concatenation of chars

If i give as below concatenation does not happen?(as i only have three characters not strings)

public String front3(String str) {
  if(str.length()<=3){
      return str+str+str;
  }
   else{
      String str2 = str.charAt(0) + str.charAt(1) + str.charAt(2);
      return str2+str2+str2;
   }

}

Open in new window

0
rrzCommented:
Without adding the empty String the chars will be interpreted as ints.
0
krakatoaCommented:
Without adding the empty String the chars will be interpreted as ints.

Maybe not quite 'interpreted', as it of course it won't even compile.
0
gudii9Author Commented:
public class Test2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Test2 t=new Test2();
        t.front3("cat");
        
	}
		public String front3(String str){
			  if(str.length()<=3){
			      return str+str+str;
			  }
			   else{
			      String str2 = "" + str.charAt(0) + str.charAt(1) + str.charAt(2);
			      return str2+str2+str2;
			   }


	}

Open in new window


I see when i remove "" i got compilation error.
But when i run above java application i do not see any console output or test green or anything like that. How do i make sure it is working in eclipse as well not just in the codingbat site. please advise
0
CEHJCommented:
But when i run above java application i do not see any console output

Why would you? You haven't output anything to the console
0
rrzCommented:
i do not see any console output
You must use print method.
public class Test2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Test2 t=new Test2();
        System.out.println(t.front3("cat"));
        
	}
		public String front3(String str){
			  if(str.length()<=3){
			      return str+str+str;
			  }
			   else{
			      String str2 = "" + str.charAt(0) + str.charAt(1) + str.charAt(2);
			      return str2+str2+str2;
			   }

        }
	}          

Open in new window

0
gudii9Author Commented:
now i see console output
catcatcat


so basically "" means nothing. Just a trick to fool java so that it thinks as string(not int) other than that it is not adding any value in above post example right? It is not even adding one space either.
0
rrzCommented:
not adding any value in above post example right? It is not even adding one space either.
Yes.
There are many ways to create a String from a char. Here are some.
 new String(new char[]{str.charAt(0)});
String.valueOf(str.charAt(0))
Character.toString(str.charAt(0))
""  + str.charAt(0)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.