What I'm trying to do is return "fizz" when a number is divisible by fizzNumber and return "fizzbuzz" when a number is divisible by fizzNumber AND buzzNumber. I know I can just make an && statement but I'm trying to use the least amount of code possible to achieve what I need. The problem here is that the nested if statement is unreachable, I'm assuming because the if statement ends after the return statement. How can I fix this so that this mimcks an && statement using a nested if while also returning both strings if the condition is true?
public String getValue(int n) {
if (n % fizzNumber == 0) {
return "fizz";
if (n % buzzNumber == 0) {
return "buzz";
}
return Integer.toString(n); // return the number itself as a String
}
}
Solution:
public String getValue(int n) {
if (n%fizzNumber==0) {
if (n%buzzNumber==0) {
// dividable by both fizzNumber and buzzNumber
return "fizzbuzz";
}
// dividable by fizzNumber only
return "fizz";
}
return Integer.toString(n);
}
or shorter (using terniary operator):
public String getValue(int n) {
return (n%fizzNumber==0) ? (n%buzzNumber==0 ? "fizzbuzz" : "fizz") : Integer.toString(n);
}
You could use this:
public String getValue(int n) {
String ret = "";
if(n % fizzNumber == 0) {
ret += "fizz";
}
if(n % buzzNumber == 0) {
ret += "buzz";
}
if(ret.equals("")) {
ret = Integer.toString(n);
}
return ret;
}
This can be optimized to:
public String getValue(int n) {
StringBuilder sb = new StringBuilder();
if(n % fizzNumber == 0) sb.append("fizz");
if(n % buzzNumber == 0) sb.append("buzz");
return sb.length() == 0 ? Integer.toString(n) : sb.toString();
}
As you can see, this solution doesn't use nested if-statements.
Related
I am trying to write code for the following string operations:
1) to reverse a string.
This is what I have:
String rev = "";
String reverse(String s){
if(s.length() == 1){
return s;
}
else {
rev += s.charAt(s.length()-1)
+reverse(s.substring(0,s.length()-1));
return rev;
}
}
2) If two strings are equal to each other.
int compareString(char a, char b, int n){
if (n == 0 || a == 0 || a != b){
return a - b;
}
else {
return(compareString(a+1, b+1, n-1));
}
}
3) if a string is a palindrome (for example, "eye" or "racecar") - reads the same forwards and backwards.
boolean checkPalindrome (String s){
if(s.length() == 0 || s.length() == 1){
return true;
}
if(s.charAt(0) == s.charAt(s.length()-1)){
return checkPalindrome (s.substring(1, s.length()-1));
}
return false;
}
I am unclear on 2. As an exercise in recursive thinking, I would prefer only recursion techniques and corrections for the above. Thank you.
If two strings are equal to each other.
When comparing two strings, you have to pass in the strings.
public static boolean isEquals(String a, String b) {
if (a.length() != b.length()) return false;
return isEquals(a, b, 0);
}
private static boolean isEquals(String a, String b, int index) {
if (index >= a.length()) return true;
if (a.charAt(index) != b.charAt(index)) return false;
return isEquals(a, b, index + 1);
}
or if performance doesn't matter
public static boolean isEquals(String a, String b) {
if (a.length() == 0)
return b.length() == 0;
if (b.length() == 0)
return false;
return a.charAt(0) == b.charAt(0) &&
isEquals(a.subString(1), b.subString(1));
}
I need to write a recursive method called indexOf that accepts two Strings as parameters and that returns the starting index of the first occurrence of the second String inside the first String (or -1 if not found). I have to solve this problem using recursion.
These are some example results:
indexOf("Barack Obama", "Bar") 0
indexOf("Barack Obama", "ck") 4
indexOf("Barack Obama", "a") 1
indexOf("Barack Obama", "McCain") -1
indexOf("Barack Obama", "BAR") -1
This is my solution but it gives me 6 for indexOf("Barack Obama", "McCain")instead of -1.
public static int indexOf(String s1, String s2) {
if(s1.equals(s2))
return 0;
else
return indexOfHelper(s1, s2, 0);
}
private static int indexOfHelper(String s1, String s2, int ctr) {
if(s2.length() > s1.length())
return -1;
if(s2.length() == 0 || s1.length() == 0) //base case
return ctr;
else //recursive case
if(s1.charAt(0) == s2.charAt(0)){ //if there is a matching character
if(s1.substring(0, s2.length()).equals(s2))
return ctr; //if there is a matching character and the rest of the strings match as well
else
return -1; //if there is a matching character but the rest of the strings don't match
}
else
return 1 + indexOfHelper(s1.substring(1), s2, ctr);
}
I must say that recursive step was quite tricky. It passes all test cases. I hope following helps. Java and C++ code here
JAVA
int indexOf (String s1, String s2) {
if (s1.length() == 0 && s2.length() == 0) {
return 0;
} else if (s1.length() == 0) {
return -1;
} else if (s2.length() == 0) {
return 0;
} else if (s2.length()>s1.length()) {
return -1;
}
else if (s1.charAt(0) == s2.charAt(0)) {
int subIndex = indexOf(s1.substring(1),s2.substring(1));
return subIndex == -1 ? -1: subIndex;
} else {
int subIndex = indexOf(s1.substring(1),s2);
return subIndex == -1 ? -1: subIndex+1;
}
}
C++ code here
int indexOf (string s1, string s2) {
if (s1 == "" && s2 == "") {
return 0;
} else if (s1 == "") {
return -1;
} else if (s2=="") {
return 0;
} else if (s2.size()>s1.size()) {
return -1;
}
else if (s1 [0] == s2[0]) {
int subIndex = indexOf(s1.substr(1,s1.length()),s2.substr(1,s2.length()));
return subIndex == -1 ? -1: subIndex;
} else {
int subIndex = indexOf(s1.substr(1,s1.length()),s2);
return subIndex == -1 ? -1: subIndex+1;
}
}
Here is my solution
public static void main(String[] args) {
System.out.println(indexOf("Ninja!", "i"));
System.out.println(indexOf("ninja2", "ja2"));
System.out.println(indexOf("ninja2", "hae"));
}
public static int indexOf(String s, String contains) {
if (contains.length() > s.length()) {
return -1;
}
return indexOf(s, contains, 0);
}
private static int indexOf(String s, String contains, int index) {
if ((s.length() - contains.length()) < index) {
return -1;
}
if (s.substring(index, index + contains.length()).equals(contains)) {
return index;
} else {
return indexOf(s, contains, index + 1);
}
}
I am trying to have my program output an error code when the input values are too high, but I can only get it to display the error message in the terminal window, not in the method return. Here is the code:
public class AckermannAdvanced {
public static long ack (long m, long n) {
long ans;
System.out.print("\f");
if (m > 3 && n > 1) {
System.out.print("Input values are too high");
} else {
if (m == 2) ans = (2*n)+3;
else if (m == 1) ans = n+2;
else if (m == 0) ans = n+1;
else if (n == 0) ans = ack(m-1, 1);
else ans = ack(m-1, ack(m, n-1));
System.out.print(ans);
return(ans);
}
return 0;
}
}
You could use a Long with a capital L, and then it is an object representing a long. Once you return an object you could return null. Java automatically converts a long to a Long when returning, so the other returns should be the same. So
public static Long ack(long m, long n) //...
//...
if (m > 3 && n > 1) {
return null;
}
Alternatively you could have it return an OptionalLong
public static OptionalLong ack(long m, long n) //...
//No result
return OptionalLong.empty();
//Result
return OptionalLong.of(21438999L);
https://www.geeksforgeeks.org/optionallong-orelselong-method-in-java-with-examples/
Not keen on using the parseInteger solution, it is ugly, and as Joshua Bloch says you should "Use exceptions only for exceptional conditions". Of course, I can use something like block of code below, but it doesn't guarantee it is an Integer.
for (char c : str.toCharArray())
{
if (!Character.isDigit(c)) return false;
}
return true;
"Use exceptions only for exceptional conditions" is a good practice to follow in general, but it's not a hard-and-fast rule. I think that this is one of the cases where using exceptions is better than the alternatives.
Since parseInteger() can return any possible int value, you can't use any other return value to indicate failure. If you know you're never going to process a particular value (such as -1 or -2147483648), you can return that as a sentinel value to indicate a parse failure.
The only alternative is to return a boolean indicating success or failure and to store the parsed value into a parameter. However, since function calls are always pass-by-value in Java, you'd need to create a new class to do this:
public class IntWrapper
{
int value;
}
...
public static boolean myParseInt(String s, IntWrapper outValue)
{
try
{
outValue.value = Integer.parseInt(s);
return true;
}
catch(NumberFormatException e)
{
return false;
}
}
...
IntWrapper value = new IntWrapper();
if (myParseInt(value))
{
// Use value.value
}
else
{
// Parsing failed
}
Given these alternatives, I think the simplest usage is just to use exceptions and deal with them appropriately, even though non-numeric input may not necessary be an "exceptional" condition.
I'd leave it with exception but if you REALLY want solution without exception you can copy method parseInt() from this site with java internal classes and change it a little bit
(You can modify it a little bit more, since you do not need result)
public static false isValidInt(String s, int radix)
throws NumberFormatException
{
if (s == null) {
return false;
}
if (radix < Character.MIN_RADIX) {
return false;
}
if (radix > Character.MAX_RADIX) {
return false;
}
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else
return false;
if (len == 1) // Cannot have lone "-"
return false;
i++;
}
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
return false;
}
if (result < multmin) {
return false;
}
result *= radix;
if (result < limit + digit) {
return false;
}
result -= digit;
}
} else {
return false;
}
return true;
}
You could use:
public static boolean isInteger(String str) {
if (str == null) {
return false;
}
int length = str.length();
if (length == 0) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length == 1) {
return false;
}
i = 1;
}
for (; i < length; i++) {
char c = str.charAt(i);
if (c <= '/' || c >= ':') {
return false;
}
}
return true;
}
Already answered here: What's the best way to check to see if a String represents an integer in Java?
I am doing a problem from codingbat and I am stuck at this problem. The question asks me to find all the 'hi' in the string but ignore the 'hi' which have 'x' just before them. In other words, don't count 'xhi' but only 'hi'.
Every input works fine in my code except for when the input is "xxxx".
My code is as follows:
public int countHi2(String str) {
String s = "hi";
int count = 0;
if(str.length() < 2) {
return 0;
}
else if(str.charAt(0) == 'x' && str.substring(1,3).equals(s)) {
count+= countHi2(str.substring(3));
}
else if(str.substring(0,2).equals(s)){
count+= 1 + countHi2(str.substring(2));
}
else {
count+= countHi2(str.substring(1));
}
return count;
}
The problem is that it throws IndexOutOfBoundsException. The link to the question can be found here.
You could do as follows :
public static int countHi2(String str) {
if (str.startsWith("xhi")) {
return countHi2(str.substring(3));
} else if (str.startsWith("hi")) {
return countHi2(str.substring(2)) + 1;
} else if (str.length() > 0){
return countHi2(str.substring(1));
} else {
return 0;
}
}
(It does not handles null value, and it is really not optimized.)
You see an exception because substring throws IndexOutOfBoundsException if the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex. You check for the length to be at least 2, and then do substring(1, 3), causing an exception.
You can avoid the problem with IndexOutOfBoundsException in substring by switching to startsWith API, which does not throw exceptions even when you compare your string to a longer one.
The problem is that if you have an 'x' at the end of your string (or at one of the last 2 positions), your substring will start at an index that is out of bounds (as your exception tells you). You could just check in that case, if str.substring(3) is feasible:
else if(str.charAt(0) == 'x' && str.substring(1,3).equals(s)) {
if (str.length() > 3) count+= countHi2(str.substring(3));
else return count;
}
line no 8 need to modify.
else if(str.length()>=3 && str.charAt(0) == 'x' && str.substring(1,3).equals(s))
{...}
Total code should be -
public int countHi2(String str) {
String s = "hi";
int count = 0;
if(str.length() < 2) {
return 0;
}
else if(str.length()>=3 && str.charAt(0) == 'x' && str.substring(1,3).equals(s)) {
count+= countHi2(str.substring(3));
}
else if(str.substring(0,2).equals(s)){
count+= 1 + countHi2(str.substring(2));
}
else {
count+= countHi2(str.substring(1));
}
return count;
}
Fixed one
public int countHi2(String str) {
String s = "hi";
int count = 0;
if(str.length() < 2) {
return 0;
}
else if(str.charAt(0) == 'x' && str.length() > 2 && str.substring(1,3).equals(s)) {
count+= countHi2(str.substring(3));
}
else if(str.substring(0,2).equals(s)){
count+= 1 + countHi2(str.substring(2));
}
else {
count+= countHi2(str.substring(1));
}
return count;
}
This code will perfome well for 'XXXX' and other combinations. But i haven't check for the all combinations.
public static int countHi2(String str) {
String s = "hi";
int count = 0;
if(str.length() < 2) {
return 0;
}
else if((str.length() >= 3) && (str.charAt(0) == 'x' && str.substring(1,3).equals(s))) {
count+= countHi2(str.substring(3));
}
else if(str.substring(0,2).equals(s)){
count+= 1 + countHi2(str.substring(2));
}
else {
count+= countHi2(str.substring(1));
}
return count;
}
you never get to this line
return count;
you are using if else all the time
when your input is 'xxxx' you keep getting to
count+= countHi2(str.substring(1));
when you have 2 letters remaining "xx" and you check the first condition, and you do str.substring(1,3) is when you get that error.
You should check that str.lenght() is not 2 in that case, for example:
public int countHi2(String str) {
String s = "hi";
int count = 0;
if(str.length() < 2) {
return 0;
}
else if(str.length()>2 && str.charAt(0) == 'x' && str.substring(1,3).equals(s)) {
count+= countHi2(str.substring(3));
}
else if(str.substring(0,2).equals(s)){
count+= 1 + countHi2(str.substring(2));
}
else {
count+= countHi2(str.substring(1));
}
return count;
}
you guys are complicating to much. here is a simple solution.
public int countHi2(String str) {
return (str.length() < 2)?0:
(str.substring(0,2).equals("xh"))?
countHi2(str.substring(2)):
(str.substring(0,2).equals("hi"))?
1 + countHi2(str.substring(1)):
countHi2(str.substring(1));
}
or if it looks too weird :
public int countHi2(String str) {
if(str.length() < 2)
return 0;
else if(str.substring(0,2).equals("xh"))
return countHi2(str.substring(2));
else (str.substring(0,2).equals("hi"))
return 1 + countHi2(str.substring(1));
else return countHi2(str.substring(1));
}
If you don't have to use recursion:
public int countHi(String test) {
if (test == null){
return 0;
}
test = test.replaceAll("xhi", "");
int n1 = test.length();
int n2 = test.replaceAll("hi", "").length();
return (n1-n2)/2;
}
Below is the code to fetch the count of 'hi' in a particular string.
public int countHi(String str) {
int count = 0;
int len = str.length();
if(len<2) {
return 0;
}
else {
if(str.substring(0,2).equals("hi")) {
return count+1+countHi(str.substring(2));
}
else {
return count+countHi(str.substring(1));
}
}
}