patternjavaModerate
Funny String Java Solution
Viewed 0 times
javasolutionstringfunny
Problem
I'm a little rusty in Java, but I'm using it to get ready for interviews. Here's the problem description from HackerRank:
Problem Statement
Suppose you have a string \$S\$ which has length \$N\$ and is indexed from \$0\$
to \$N−1\$. String \$R\$ is the reverse of the string \$S\$. The string \$S\$ is funny
if the condition \$|S_i−S_{i−1}|=|R_i−R_{i−1}|\$ is true for every \$i\$ from 1 to
\$N−1\$.
(Note: Given a string str, stri denotes the ascii value of the ith
character (0-indexed) of str. |x| denotes the absolute value of an
integer x)
Input Format
First line of the input will contain an integer T. T testcases follow.
Each of the next T lines contains one string S.
Constraints
Output Format
For each string, print Funny or Not Funny in separate lines.
This passing solution took me about 20 minutes, so that might be a bit long given the difficulty of the problem. I'm open to critiques on my speed too.
Problem Statement
Suppose you have a string \$S\$ which has length \$N\$ and is indexed from \$0\$
to \$N−1\$. String \$R\$ is the reverse of the string \$S\$. The string \$S\$ is funny
if the condition \$|S_i−S_{i−1}|=|R_i−R_{i−1}|\$ is true for every \$i\$ from 1 to
\$N−1\$.
(Note: Given a string str, stri denotes the ascii value of the ith
character (0-indexed) of str. |x| denotes the absolute value of an
integer x)
Input Format
First line of the input will contain an integer T. T testcases follow.
Each of the next T lines contains one string S.
Constraints
- \$1 \le T \le 10\$
- \$2 \le\$ length of S \$\le 10000\$
Output Format
For each string, print Funny or Not Funny in separate lines.
This passing solution took me about 20 minutes, so that might be a bit long given the difficulty of the problem. I'm open to critiques on my speed too.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
private static boolean isFunny (String s)
{
String rev = reverse(s);
boolean stillEq = true;
for (int i = 2; i 0)
return s.charAt(s.length()-1) + reverse(s.substring(0, s.length()-1));
else
return "";
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int tests = sc.nextInt();
for (int i = 0; i < tests; ++i)
{
String out = isFunny(sc.next()) ? "Funny" : "Not Funny";
System.out.println( out );
}
}Solution
-
Bug
The main loop starts at
-
Naming
A name
-
Algorithm
Reversal of the string just wastes time. You may work the same string from both directions simultaneously:
-
Returning the comparison result is an anti-pattern.
achieves the same result as
in a much cleaner way.
Bug
The main loop starts at
i = 2. That is, s.charAt(1) - s.charAt(0) is never attended to. Suspicious, isn't it?-
Naming
A name
comp (and comp2) presumes that it carries some information about comparison. It obviously doesn't. diff and rdiff sound better.-
Algorithm
Reversal of the string just wastes time. You may work the same string from both directions simultaneously:
for (int i = 1; i < s.length(); ++i) {
diff = s.charAt(i) - s.charAt(i - 1);
rdiff = s.charAt(s.length() - 1 - i) - s.charAt(s.length() - 1 - (i-1));
...-
Returning the comparison result is an anti-pattern.
return stillEq;achieves the same result as
if (stillEq)
return true;
else
return false;in a much cleaner way.
- If you insist on reversing a string, better come up with an iterative method. Java cannot eliminate tail recursion.
Code Snippets
for (int i = 1; i < s.length(); ++i) {
diff = s.charAt(i) - s.charAt(i - 1);
rdiff = s.charAt(s.length() - 1 - i) - s.charAt(s.length() - 1 - (i-1));
...return stillEq;if (stillEq)
return true;
else
return false;Context
StackExchange Code Review Q#105565, answer score: 12
Revisions (0)
No revisions yet.