Online challenge on Hacker Rank.
Problem Description
Alice wrote a sequence of words in CamelCase as a string of letters,
S
, having the following properties:It is a concatenation of one or more words consisting of English letters. All letters in the first word are lowercase. For each of the subsequent words, the first letter is uppercase and rest of the letters are lowercase. Given, print the number of words in on a new line.
Input Format
A single line containing string
S
.Constraints
Output Format
Print the number of words in string.
Sample Input
saveChangesInTheEditor
Sample Output
5
public class Solution {
private static int solve(String input) {
int len = input.length();
if (len == 0) {
return 0;
}
int count = 1;
for (int i = 0; i < len; i++) {
char c = input.charAt(i);
if ('A' <= c && c <= 'Z') {
count++;
}
else if (c == ' ') {
break;
}
}
return count;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.next();
System.out.println(solve(s));
}
}
1 Answer 1
Glaring Deficiencies
What are you doing? You haven't bothered to explain your algorithm, either in the question body or in program comments.
Bugs. As pointed out by @Abhisek, your code prints 3 instead of 2. When you count the number of camelCase words, you should ignore whitespace, in fact, you should treat any non-alphabetic characters as lower-case, as per my understanding of the problem (although this is an edge case).
You haven't bothered to use any of Java's standard libraries. You would find the functions
Character.isUpperCase(char)
,Character.isLowerCase(char)
andCharacter.isWhitespace(char)
extremely useful, instead of doing error-prone and language-limited manual checking. Also,String.isEmpty()
is always a better check thanString.length() == 0
.Non-descriptive naming. Your method does indeed solve a HackerRank problem, but that does not describe it properly. You could name it for what it does, something like
getCamelCaseWordCount(String)
, as per some guidelines for Java method naming (Effective Java by Joshua Bloch).You only use
len
once without the emptiness check. In fact, that is not required either, as the general code will handle that too. Just use the emptiness check to set the initial value of the word count to0
or1
, depending on whether the input is empty or non-empty. respectively. You do not need to return early to avoid the loop as the loop won't iterate in the first place.For that matter, as
String
s are immutable, repeatedly calling.length()
on the sameString
object does not have much overhead, so you do not needlen
even if you are concerned about the loop.Avoid all the
len
business, and use a for-each loop. Kind of like:for(char c : input.toCharArray()){//for JDK 1.5+ ... }
OR,
for(char c : input.chars()){//for JDK 1.8+ ... }
As usual, this is a 1-liner with Java 8 streams. This is an exact equivalent:
return in.isEmpty() ? 0 : 1 + in.chars().filter(Character::isUpperCase).count();
Note that the above returns a
long
, not anint
. That's as per the Stream API.
Putting it all together,
Modified Code
public class Test{
public static long getCamelCaseWordCountNormal(String in){
long words = in.isEmpty() ? 0 : 1;
for(char c : in.toCharArray()){
if(Character.isUpperCase(c)){
words++;
}
}
return words;
}
public static long getCamelCaseWordCountStreams(String in){
return in.isEmpty() ? 0 : 1 + in.chars().filter(Character::isUpperCase).count();
}
}
Explore related questions
See similar questions with these tags.
CodeReview
, your code will produce output 3 instead of 2 \$\endgroup\$i != 0
in the second condition, etc). Feel free to add any other improvements \$\endgroup\$