So I'm making a fraction calculator and I have one last part to figure out. For calculations that involve multiplying by 0, the final answer must always be 0. Due to my code I always end up with something like 0/1 or 0/5, so it always has a denominator. I want to return the answer without that denominator, but I'm not sure how to write my if statement. Here's my attempt at trying to print the 0 without the denominator.
if (reducedAnswer.charAt(0) == 0) {
return reducedAnswer.substring(0, 1);
}
I'm not quite sure how to modify that if statement to check if the first character of the answer is 0 so I can remove the unwanted parts. Any ideas?
You need a char literal, change
if (reducedAnswer.charAt(0) == 0) {
to
if (reducedAnswer.charAt(0) == '0') {
or use String.startsWith like
if (reducedAnswer.startsWith("0")) {
Related
problem link: https://leetcode.com/problems/string-to-integer-atoi/
i have implemented my solution but it fails for testcase like "-+42"since 2 consecutive signs appear in string. what changes do i need to do in my code, and where am i wrong? help would be appreciated
my code:
class Solution {
public int myAtoi(String s) {
s=s.trim();
char sign='+';
if (s.length()==0) return 0;
String digit="";
for(int i=0;i<s.length();i++)
{
//checking for sign
if(s.charAt(i)=='-'||s.charAt(i)=='+')
sign=s.charAt(i);
//checking for all non digit characters
else if((s.charAt(i)>='a'&& s.charAt(i)<='z')||(s.charAt(i)>='A' && s.charAt(i)<='Z')||(s.charAt(i)==' ')||(s.charAt(i)=='.')||(s.charAt(i)=='-')||(s.charAt(i)=='+'))
break;
else{
digit=digit+s.charAt(i);
}
}
if(digit=="") return 0;
//System.out.print(sign);
try{
int n=(Integer.parseInt(digit));
//int a=Integer.parseInt(digit);
System.out.print(sign);
if(sign=='-')
return (-n);
return n;
}
//check for out of range for integer
catch(NumberFormatException e)
{
if(sign=='-')
{
//
int n=Integer.MIN_VALUE;
return n;}
else
{
int n=Integer.MAX_VALUE;
return n;
}
}
}
}
Er, just.. do what the exercise says? Not sure what you want to hear from SO here. I guess: "Can you regurgitate the question to me". Can do!
Your algorithm isn't doing anything like what the exercise spells out you need to do. You are triggering on a sign character appearing anywhere, and your code scans for letters, all things which the exercise doesn't mention. At all. The exercise mentions the concept of a 'not a digit' and the first character (after getting rid of spaces, which you already did with a trim() invocation).
So, do what the exercise says:
Instead of if (s.charAt(i) == '-' your code needs to involve s.charAt(0) - there are only 3 options:
The trimmed string starts with a +. Set the sign to +, and start looking at digits from position 1.
The trimmed string starts with a -. Set the sign to -, and start looking at digits from position 1.
Neither. Set the sign to + and start looking at digits from position 0.
Your s.charAt(i) >= 'a' is also wrong. You're not looking for a letter. You're looking for anything that isn't a digit. + isn't a letter. Nevertheless, in input -5+10, you're supposed to return -5. In -+10 you're supposed to return 0. (Because that's like -hello - the negative value of no digits, which is minus zero, which is just zero).
I think the intent of the exercise is not to use Integer.parseInt whatsoever.
Try this algorithm:
if your character is >= '0' and <= '9', you can subtract '0' to get the actual digit in integer form: char c = '5'; int y = c - '0'; System.out.println(y); would print 5.
multiply your existing input by 10, then add the digit you have. In other words, for text input "29", first you read a 2, you multiply the number you're working on (0, at first) to 10 (still 0), then you add 2, giving you 2. Then you get another digit, so you multiply what you ahve so far by 10 (giving you 20), and add the digit value, getting you the integer 29. No need for parseInt.
You now you need to clamp when your working total flips signs on you. So, if all of a sudden your input is negative (as you won't yourself make it negative until the very end), you know you have to clamp and return Integer.MIN_VALUE or Integer.MAX_VALUE, depending on the sign value.
I'm trying to write a program that that will find if there's an equal number of odds and even numbers in a given one, it's working great but it want to use conditional operator instead of these 4 rows (the // rows),
I'm getting this:
Syntax error on token "%", invalid AssignmentOperator
Can someone tell me why? What's wrong?
while(number!=0) {
//if(number%2==0)
//even++;
//else
//odd++;
number%2==0 ? even++ : odd++;
number/=10;
}
number%2==0 ? even++ : odd++;
This is not a statement. The result of a ternary must be assigned to something:
int x = number % 2 == 0 ? even++ : odd++;
However, this is stylistically quite awkward. I would use an if-else (i.e., what you originally had) over this pattern. Here you've created a temporary variable that you're never going to reuse, for the sole purpose of using a ternary.
It requires a variable at the left side at where you can place the value after the condition.
int tmp = (number%2 == 0)?even++:odd++;
number%2==0 ? even++ : odd++;
This statement is not assigning any value to number.As per my knowledge its always recommended for use if-else instead of ternary operator.
Because, in ternary operator the false/else part is compulsory to write, where in if-else else/false part is optional.
while(number!=0) {
//if(number%2==0)
//even++;
//else
//odd++;
int temp= number%2==0 ? even++ : odd++;
number/=10;
}
Now, temp variable is holding the value .
I am really confused by a CodingBat Java exercise. It's suppose to return true if the given string contains an appearance of "xyz" where the xyz is not directly preceeded by a period (.). So "xxyz" counts but "x.xyz" does not.
xyzThere("abcxyz") → true
xyzThere("abc.xyz") → false
xyzThere("xyz.abc") → true
I couldn't figure this out for the life of me so I just looked up a solution online and I'm so confused why this works. Any wanna help clarify? I added some comments on the code as to what I am having trouble with.
public boolean xyzThere(String str) {
int pos =0;
while ((pos = str.indexOf("xyz")) >= 0) { `
The while ((pos = str.indexOf("xyz")) >= 0) { confuses me here. I tried this without the double brackets and it didn't work. Does the double brackets do some kind of casting to an int or something? Also how does pos even get assigned to something in a while statement, does it run the part on the right first then assigns it?
if (pos == 0)
return true;
if (str.charAt(pos-1) != '.')
return true; // found it
// xyz was preceded by a period so skip over this match
str = str.substring(pos+1);
I am so confused how it can even reach str = str.substring(pos+1); I thought I could just take this out entirely but it broke the entire program. Since it's an if statement and it has no brackets to make it a block statement, how or when is this reached, and what is the logic behind it? What the purpose of this statement, as it seems so pointless to me. Even if it does get reached in the code, what does it do?
}
return false; // no luck
}
For any readers, here's the xyzThere problem: http://codingbat.com/prob/p136594
Since you were initially looking for any solution, here's a non-looping solution:
public boolean xyzThere(String str) {
return str.replaceAll("\\.xyz", "").contains("xyz");
}
Regarding double parens: if you remove the double parens, then it won't compile, because the compiler interprets that as trying to assign str.indexOf("xyz") >= 0 to the pos variable, and the types, boolean and int respectively, don't match.
You will notice that assignment is at the bottom of java operator precedence - without the extra parens, it will occur last: http://www.cis.upenn.edu/~palsetia/java/precedenceTable.html
unle
Regarding assignment in a loop - yes this is valid. The value assigned to pos is then compared with 0.
Regarding str = str.substring(pos+1);. This is how the posted solution is removing ".xyz" from the string which finally determines whether the string still contains "xyz".
Regarding the if statement
if (str.charAt(pos-1) != '.')
return true; // found it
Without brackets, the implied scope of the if statement if the next statement. The style here is generally considered back practice for just the reason you've found and should be rewritten as either:
if (str.charAt(pos-1) != '.') {
return true;
}
or
if (str.charAt(pos-1) != '.') return true;
while ((pos = str.indexOf("xyz")) >= 0) {
indexOf returns -1 if the string is not found so this is going to continue looking so long as an "xyz" is found in the string. See later for how it makes sure this is another occurrence rather than the same one again.
The extra bracket is to stress that there is also an assignment going on here. pos is being updated to the start of the "xyz" that was found (or -1 if no more).
if (pos == 0)
return true;
It is allowed at the start - I guess.
if (str.charAt(pos-1) != '.')
return true;
If there is not a "." just before it then we're done.
str = str.substring(pos+1);
Throw away everything up to and including the "x" of the discovered "xyz". Makes sure that next time around we don't find the same one again.
return false;
We got to the end without finding one - it must not be there.
The following code snippet needs "double brackets" (really double parentheses -- it pays to be precise because brackets are a different character) because the parens group different parts of what amounts to a mathematical expression. What you think are double brackets are actually single parens grouping different parts of the expression from what you probably think they're grouping.
while ((pos = str.indexOf("xyz")) >= 0)
^-----^
^------------------------^
^-------------------------------^
If you switch to an IDE instead of the simple text editor that you're probably using, the IDE will highlight matching parentheses so you can see which opening paren is related to which closing paren. There's no casting or other magic going on. Parentheses, brackets, angle brackets, and curly braces. are just there to show the beginning and end of particular groups of things, whether it's an expression, an expression within an expression, a data set, etc.
I am trying to create a method that converts Decimal to Binary. Here is what I wrote so far (which is not working properly):
public static String D2B(int decimal){
String binaryValue="";
for (int tempDecimal=decimal;0==tempDecimal;tempDecimal/=2){
binaryValue=tempDecimal%2+binaryValue;
}
return binaryValue;
}
public static void main(String[]args){
int myValue=127;
System.out.println(D2B(myValue));
}
I think the condition in your loop is incorrect:
for(int tempDecimal=decimal;0==tempDecimal;tempDecimal/=2)
Note that this loops while tempDecimal is equal to 0, which means that the loop should not loop at all for nonzero inputs and will loop forever for zero inputs. Try rewriting it as
for(int tempDecimal = decimal; 0 != tempDecimal; tempDecimal /= 2)
Also, watch out for 0 as an input and for negative numbers as inputs; they won't come out correctly with your current approach.
A few other minor nits:
I strongly suggest indenting your code correctly and putting spaces in-between the operators for readability. It makes the code much easier to read, and I think you would have spotted the bug more easily had you had more spaces.
There's no reason to create a second variable tempDecimal in this function. Java parameters are passed by value, so changes you make to the argument won't show up in the caller. Since you're not using the decimal value anywhere else, the extra variable is superfluous.
Hope this helps!
First of all I am not asking for people to "do my homework" like I have seen others on here ask for. I have managed to code a working iterative version of a program that determines if a string is a palindrome or not. Spaces, punctuation and special characters are ignored while determining if the string is a palindrome. This version does work but when I try and apply recursive statements in the "isPalindrome()" method I get Stack Overflow errors. I know what these errors are, it's just that applying a recursive method in a program like this is quite hard for me to get my head around (I only got taught about them 2 weeks ago). Anyway here is the code I have managed to compile (and run) so far:
/** Palindrome.java: A sigle application class that determines if a word or a string
* is a palindrome or not. This application is designed to ignore spaces between
* chars, punctuation marks and special characters while determining if the word or
* string is a palindrome or not.
*
**/
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.regex.*;
public class Palindrome{
static String palindrome, str, str2, str3;
/** The main method of the Palindrome application. Takes input from the
* user, removes spaces from their input, turns their string input into
* lowercase and then all non letter characters are taken out of the user's
* input. Finally the recursive method determines if the string entered in
* by the user is a palindrome.
*
* #param args Takes in a string array of arguements
**/
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while(input.hasNext()){
str = removeSpaces(input.nextLine());
str2 = str.toLowerCase();
str3 = normalise(str2);
}
System.out.println(isPalindrome(str3));
}
/** The default constructor
**/
public Palindrome(){
}
/** isPalindrome(): A boolean method that is passed through a String input
* and uses a for loop, two inner while loops and an if-else to determine
* whether the users input is a palindrome.
*
* #param s The string input to be tested
* #return true The users input is a palindrome
* #return false The users input isn't a palindrome
**/
public static boolean isPalindrome(String s){
int first, last;
for(first = 0, last = s.length()-1 ; first < last ; first++ , last-- ){
while( (int)s.charAt(first) < 'a' || (int)s.charAt(first) > 'z' ){
first++;
}
while( (int)s.charAt(last ) < 'a' || (int)s.charAt(last ) > 'z' ){
last--;
}
}
if( first > last || s.charAt(first) != s.charAt(last) ){
//return isPalindrome(s.substring(0, s.length()-1)) == false;
return false;
}
else{
//return isPalindrome(s.substring(0, s.length()-1)) == true;
return true;
}
}
/**
* This method takes out punctuation marks in the string parsed
* through, using Java's regular expressions (regex) and Java's
* inbuilt method replaceAll(). The regex expression is passed
* through the replaceAll() method to remove all non alpha-numeric
* characters from the string passed through the method's parameter.
*
* #param t The string that will have punctuation stripped from it.
*
* #return t The string has had all non alpha-numeric characters
* removed and the new string is then returned.
*/
public static String normalise(String t){
t = t.replaceAll("[^a-zA-Z0-9]", "");
return t;
}
/** removeSpaces(): A method that deletes spaces from the users input
* and then decrements the string length count so any indexes aren't missed
* when it is incremented.
*
* #param s The string which is going to have it's spaces removed.
* #return temp The new string is then returned after the spaces have been taken out.
**/
public static String removeSpaces(String s){
StringBuilder temp = new StringBuilder(s); //creates a new StringBuilder with the inputted String
for(int i = 0; i < temp.length(); i++){ //do this for the entire length of the StringBuilder
if(temp.charAt(i) == ' '){ //if the char at i is a space
temp.deleteCharAt(i); //remove the char
i--; //subtract 1 from the counter so we don't miss an index when we increment it
}
}
return temp.toString(); //return the new String
}
}
I have blanked out the recursive statements in the recursive method for now. If someone can tell me what exactly I have done wrong and also help me in implementing a solution that would be really good. I would rather stick with the iterative version because I understand the mechanics of it, but have been asked to do a recursive version (I have been Java coding since after my mid year break last year but am a relative novice at recursion) which is proving to be quite a challenge. If you alter the code and it ends up working with the recursive version please explain how, when, why etc with your alterations. Am not looking for someone to just do this for me, I'm wanting to learn and it seems that I have learned best by example (I did get a B pass last year by analysing examples and reading explanations of implementations). Many thanks :).
EDIT: I think I have got the recursion going ok now, just the logic is the thing confusing me at the moment. Here is the recoded version of the isPalindrome() method:
public static boolean isPalindrome(String s){
int first, last;
boolean isPalindr = true;
if (s.length() <= 1){
return true; // Base case
}
for(first = 0, last = s.length()-1 ; first < last ; first++ , last-- ){
// while( (int)s.charAt(first) < 'a' || (int)s.charAt(first) > 'z' ){
// first++;
// }
// while( (int)s.charAt(last ) < 'a' || (int)s.charAt(last ) > 'z' ){
// last--;
// }
// }
if( first == last || s.charAt(first) == s.charAt(last) ){
//return isPalindrome(s.substring(first, last));
return isPalindrome(s.substring(first, last)) == true;
//isPalindr = false;
}
else{
return isPalindrome(s.substring(first, last)) == false;
//isPalindr = true;
}
}
return isPalindr;
}
If someone can help me with the logic I think this will be fixed :).
Removing all of the code that has nothing to do with the problem leaves us with this:
public static boolean isPalindrome(String s){
for loop {
isPalindrome();
}
}
isPalindrome calls isPalindrome calls isPalindrome, etc... infinitum.
The difference between this and a proper recursive function is that a recursive function will have some sort of conditional statement, breaking the cycle of the function calling itself. The flow of execution will go like this:
isPalindrome(1) begins execution and calls isPalidrome(2)
isPalindrome(2) begins execution and calls isPalidrome(3)
isPalindrome(3) begins execution and calls isPalidrome(4)
isPalindrome(4) begins execution and calls isPalidrome(5)
isPalindrome(5) begins execution and returns to isPalindrome(4)
isPalindrome(4) resumes execution and returns to isPalindrome(3)
isPalindrome(3) resumes execution and returns to isPalindrome(2)
isPalindrome(2) resumes execution and returns to isPalindrome(1)
isPalindrome(1) resumes execution and returns.
If that explanation doesn't help, think of it like this. Suppose someone was handing you plates, one at a time, to see if you can hold 25 plates at a time. It would go something like this:
Plate 1 is given to you. Are there 25 plates? No. Add another plate.
Plate 2 is stacked on top of Plate 1. Are there 25 plates? No. Add another plate.
Plate 3 is stacked on top of Plate 2. Are there 25 plates? No. Add another plate.
...
Plate 24 is stacked on top of Plate 23. Are there 25 plates? No. Add another plate.
Plate 25 is stacked on top of Plate 24. Are there 25 plates? Yes. Mission Accomplished. Now, let's put the plates back.
Plate 25 is removed.
Plate 24 is removed.
...
Plate 3 is removed.
Plate 2 is removed.
Plate 1 is removed.
Here's how that might be coded:
bool stackPlates(int i){
plateStack.addPlate();
if (plateStack.wasDropped == true) { return false; } // Were the plates dropped? Return FALSE to indicate failure.
else if (i < 25) { return stackPlates(i+1); } // Are there 25 plates yet? If not, add another.
else { return true; } // There are 25 plates stacked. Return TRUE to indicate success.
plateStack.removePlate(i);
}
Here's stackPlates(int i) called from another function:
bool success = stackPlates(1);
if (success==TRUE) { cout << "CONGRATULATIONS! YOU STACKED 25 PLATES!"; }
else { cout << "YOU BROKE THE PLATES! BETTER LUCK NEXT TIME!"; }
What your function needs to do in order to work properly is do this:
bool isPalindrome(string s, int i) {
char first = s[i]; // REPLACE THIS WITH THE CODE TO SKIP SPACES & SPECIAL CHARACTERS
char last = s[(s.length -1) -i]; // REPLACE THIS WITH THE CODE TO SKIP SPACES & SPECIAL CHARACTERS
if ( first != last ) { return false; } // return false if mismatch letter
else if ( i >= (s.length/2) ) { return true; } // return true if string fully checked
else { return isPalindrome(s, i+1); } // string not fully checked; move to next letter
}
You're experiencing stack overflows because the else branch at the bottom of the function is executed when (first <= last && "characters are equals"), so you keep recurring on the case where your string is composed by one character.
By the way, I think your code is not using recursion cleanly: you should preprocess your string only one time before starting recurring on the string, and the code that performs the palindrome recursion should be far simpler.
For any given entry into isPalindrome, it's going to recursively call itself regardless because you have no condition on your else. So, if it meets the criteria "first > last || s.charAt(first) != s.charAt(last)", it's going to recursively call isPalindrome, then the next call is too, even if it hits the else.
I don't know what a Palindrome is or what the real solution to the problem is, but that's why you're getting the stack overflow error. I suspect you need to add another condition to your else such that it will stop recursively calling itself.
When writing a recursive function the best way to go about this is usually to decide on a base case (:like "" is a palindrome, though so is "a" ... ) and then devise a method to take any state and move it to the base case.
So in the case of the palindrome, it's the same basic idea as before, if the first character and the last character are the same you return true and check the rest of the string ( thus moving closer to the base case ) and if they are not then you return false.
Your stack overflow comes from calling isPalindrome in every case rather than when you need to continue solving the problem, don't forget that if two characters mean that something isn't a palindrome, the rest is rendered irrelevant ( and thus needn't be recursed on )
Your recoded version is a bit strange, because it's still using a loop when it doesn't need to. In particular, your code will never go beyond the first iteration in your loop, because in the embedded if-else statement, you're going to return a result no matter what, so your function will always exit during the first iteration (unless there are no iterations at all).
Recursion should be approached by
Identifying a base case, i.e. a simplest case that can be solved
Re-representing a larger problem as a partial solution followed by the same, but smaller problem.
The base case you've handled correctly; any String which is length 1 or less is automatically a Palindrome.
The next step is to consider a larger problem, perhaps some string abcwewe....ba. How can we break this down into a simpler problem? We know that we'd normally check whether something is a palindrome by checking the letters one by one in pairs, starting at the ends, but then we also realise that each time we check the letters, we just repeat the same problem again and solve it the same way.
In the string I gave above, we check and verify that the first letter a is the same as the last letter a, so that's kind of a partial solution. Now we we end up with is the smaller word bcwewe....b, and it's the same problem again: Is this new String a palindrome also?
Thus, all you have to do now is to invoke the recursive call, but this time with the substring beginning with the 2nd character to the 2nd to last character. You can code the answer in just two lines, as below:
public static boolean isPalindrome(String s) {
if (s.length() <= 1) return true; // base case
return s.charAt(0) == s.charAt(s.length()-1) && isPalin(s.substring(1,s.length()-1)); // recursive case
}
One point to note is that I'm using the short circuit &&, so if the first condition fails (checking first and last character), then Java will not invoke the recursion.