Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
leetcode 680 https://leetcode.com/problems/valid-palindrome-ii/ asks to find a palindrome after deleting at most one character from it. I wrote the following code, but it turns out to fail for string "aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga" because the r value becomes 80 in the ends program entering the outer else case in which the functions return false. The program has passed the most tests so I'm not sure what's the problem of this program.
public boolean validPalindrome(String s) {
int l = 0, r = s.length() - 1;
boolean deleted = false;
while (l < r) {
System.out.println(s.charAt(l));
if (s.charAt(l) == s.charAt(r)) {
l++;
r--;
} else if (!deleted) {
deleted = true;
if (s.charAt(l + 1) == s.charAt(r)) {
l++;
} else if (s.charAt(l) == s.charAt(r - 1)) {
r--;
} else {
return false;
}
} else {
return false;
}
}
return true;
}
This test fails because you assume that only one of the two conditions in
if (s.charAt(l + 1) == s.charAt(r)) {
l++;
} else if (s.charAt(l) == s.charAt(r - 1)) {
r--;
Is true. In the given test case when l=19 and r=81 both are true so you need to decide which one to apply.
To demonstrate the issue change the order of the two conditions:
if (s.charAt(l) == s.charAt(r-1)) {
r--;
} else if (s.charAt(l+1) == s.charAt(r)) {
l++;
The change does not fix the issue, just demonstrate it.
(You may find this helpful: What is a debugger and how can it help me diagnose problems?)
Related
This question already has answers here:
What's the simplest way to print a Java array?
(37 answers)
Closed 3 years ago.
Here is my code:
public boolean isBST() {
return isBST(this.root);
}
private boolean isBST(BinaryNode<T> rootNode) {
if (rootNode == null) {
return false;
}
if (rootNode.isLeaf()) {
return true;
}
T left = null;
T right = null;
if (rootNode.hasLeftChild()) {
left = rootNode.getLeftChild().getData();
if (left.compareTo(rootNode.getData()) < 0) {
return this.isBST(rootNode.getLeftChild());
}
else {
return false;
}
}
if (rootNode.hasRightChild()) {
right = rootNode.getRightChild().getData();
if (right.compareTo(rootNode.getData()) > 0) {
return this.isBST(rootNode.getRightChild());
}
else {
return false;
}
}
return true;
}
This code works for simple binary trees, but it doesn't work for other ones. Such as if I have a tree like so:
5
/ \
3 6
/\
1 2
It won't mark it false even thought it should since 2 is smaller than 3 and is in the wrong place. My code just checks the left child's left children, and the checks the right child's right children and not the inner children. What can I do to make this code work in the way that I wrote it? How can I modify it?
The bug is in the line
return this.isBST(rootNode.getLeftChild());
You must not exit the method just because the left part is checked (if it exists).
Instead of
if (left.compareTo(rootNode.getData()) < 0) {
return this.isBST(rootNode.getLeftChild());
}
else {
return false;
}
this should do the expected:
if (left.compareTo(rootNode.getData()) >= 0 ||
!this.isBST(rootNode.getLeftChild()) {
return false;
}
(For symmetry reasons you may also want to rewrite the right part check in a similar way, however this is not required. Your could would also work in its current form.)
I think all you need to do is when you recursively look left and right only return if it's false
if (rootNode.hasLeftChild()) {
left = rootNode.getLeftChild().getData();
if (left.compareTo(rootNode.getData()) < 0) {
boolean isValid = this.isBST(rootNode.getLeftChild());
if (!isValid) {
return false;
}
} else {
return false;
}
}
if (rootNode.hasRightChild()) {
right = rootNode.getRightChild().getData();
if (right.compareTo(rootNode.getData()) > 0) {
boolean isValid = this.isBST(rootNode.getRightChild());
if (!isValid) {
return false;
}
} else {
return false;
}
}
return true
It looks like, at a quick look, the return is happening before the right side is checked.
Slightly more succinct version that also supports duplicates appearing only on the right (if you want to allow duplicates on the left then swap the >= in left comparison for <= in the right comparison
if (rootNode.hasLeftChild()) {
left = rootNode.getLeftChild().getData();
if (left.compareTo(rootNode.getData()) >= 0) || !this.isBST(rootNode.getLeftChild()) {
return false;
}
}
if (rootNode.hasRightChild()) {
right = rootNode.getRightChild().getData();
if (right.compareTo(rootNode.getData()) < 0 || !this.isBST(rootNode.getRightChild()) {
return false;
}
}
return true;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
This while code works fine, it is a program to check for palindromes.
public class Solution {
public static boolean checkPalindrome(String str){
int i=0;
int j= str.length()-1;
while(i<j)
{
if(str.charAt(i)!=str.charAt(j))
{
return false;
}
i++;
j--;
}
return true;
}
}
But what will happen in this version, what do you expect the output to be in this?
public class Solution {
public static boolean checkPalindrome(String str){
int i=0;
int j= str.length()-1;
while(i<j)
{
if(str.charAt(i)!=str.charAt(j))
{
return false;
}
else
{
return true;
}
i++;
j--;
}
}
}
In your second code block you are first checking if the first character is the same as the last.
If it isn't, return false.
Else, return true.
So this isn't going to be a valid palindrome check. It only checks if the first and last letters are the same or not and ignores the letters in the middle.
I am currently trying to come up with a code that will scan a string
and check to see if there is an even number of open and closing brackets on each line. If so, it would return true. (Excuse me for the incorrectness in formatting but I could not get the examples to properly take shape unless I identified it as code)
{} // The code would return true
{{}}
{}{}
{{{}{{}}}}
} // The code would return false
{}
}}{
{{{}{}
What I tried so far:
public boolean bracketsMatch(String brackets)
{
int lb = 0;
int rb = 0;
int i = 0;
while (brackets.charAt(i) == '{' || brackets.charAt(i) == '}' || brackets.charAt(i) == '')
{
if (brackets.charAt(i) == '{')
{
lb += 1;
}
if (brackets.charAt(i) == '}')
{
rb += 1;
}
if (brackets.charAt(i) == '')
{
if (lb / rb == 2)
{
// Is it possible to get the code scan the next line to next line?
// need an extra statement here for ^^ before I can place the if statement below
if (bracket.charAt(i + 1) == '')
{
return true;
}
}
else
{
return false;
}
}
i++
}
}
I apologize in advance for any experienced programmers as this would be an inefficient nightmare. I am relatively new to programming in general. I attempted to have the code check for the number of left brackets (lb) and right brackets (rb). Whenever the code came to an empty string, it would divide lb by rb. If the code did not equal 2, the code would return false. I probably have more than a dozen errors in this code, but I was wondering if there was any way to have the code go onto the next line to scan the next set of brackets. Thanks for any help in advance.
EDIT 1:
public boolean bracketsMatch(String brackets)
{
int balance = 0;
for (int i = 0; i < brackets.length(); i++)
{
char value = brackets.charAt(i);
if (value == '{')
{
balance += 1;
}
else if (value == '}')
{
balance -= 1;
}
}
if (balance != 0)
{
return false;
}
else
{
return true;
}
}
This won't compile, as '' is an invalid character literal:
if (brackets.charAt(i + 1) == '')
And your current approach of counting opening and closing brackets,
and checking the value of lb / rb won't yield the right result.
You don't need to count the right brackets. You only need to count the open brackets, and reduce that count as they get closed.
Here's a sketch of an algorithm you can use,
I hope to not spoil the exercise:
For each character in the string
If it's an open bracket, increment the count
If it's a close bracket
If the open count is 0, there's nothing to close, so they are not balanced, we can stop
Decrement the count
After all characters, if the open count is 0, the brackets are balanced
As an additional code review note, this is bad in many ways:
if (brackets.charAt(i) == '{') {
// ...
}
if (brackets.charAt(i) == '}') {
// ...
}
What's bad:
Calling brackets.charAt(i) repeatedly is unnecessary if the result will always be the same. Call it once and save the result in a variable.
The two if conditions are exclusive: if the first is true, the second won't be true, so it's pointless to evaluate it. The second condition should be if else instead of if. And instead of an if-else chain, a switch could be more interesting here.
Instead of calling the string brackets, it would be better to call it something more general. What if the actual input is "{something}"? Then it contains more than just brackets, but the algorithm would work just the same. Calling it brackets is misleading.
Alternative way to do
You can use Java Stack class [As it represent the List-In-First-Out stack of object].You can use the push and pop method of Stack class. Here is the implementation.
public class BracketMatching {
public static boolean bracketMatch(String input){
Stack<Character> st = new Stack<>();
for(char c : input.toCharArray()){
if( c == '{')
st.push(c);
else if(c == '}'){
if(st.isEmpty())
return false;
st.pop();
}
}
if(st.isEmpty())
return true;
return false;
}
public static void main(String[] args){
String input1 = "{}{{}}{}{}{{{}{{}}}}";
String input2 = "}{}}}{{{{}{}";
System.out.println(bracketMatch(input1));
System.out.println(bracketMatch(input2));
}
}
I try to refactor a code so that it will use separate methods to do some calculations. Just to make it clear.
What I want to know is, is it a good practice or a bad one to write a separate method to find out a simple thing like a number is odd or even ?
The original code is ,
int n = 11;
if (n % 2 == 0) {
System.out.println("Not selected");
} else {
boolean isPrime = true;
if (n == 0 || n == 1) {
isPrime = false;
} else {
int i = 2;
double a = Math.sqrt(Math.abs(n));
while (i <= a) {
if (n % i == 0) {
isPrime = false;
}
++i;
}
}
if(isPrime){
System.out.println("Prime it is");
}
}
The refactored code is,
int n = 11;
if (isEven(n)) {
System.out.println("Not selected");
} else {
if (isPrime(n)) {
System.out.println("Prime it is");
}
}
public static boolean isEven(int n) {
return n % 2 == 0 ? true : false;
}
public static boolean isPrime(int n){
if(n==0 || n==1)return false;
int i=2;
double a = Math.sqrt(Math.abs(n));
while(i<=a){
if(n%i==0){
return false;
}
++i;
}
return true;
}
It's generally considered good practice to break code down into separate methods for things like readability, length, or cyclomatic complexity, especially if you are not changing how the code works.
Boolean expressions, like what you have extracted, are often good choices for a quick extract function refactor. It allows a reader of the code base to know why a boolean expression is important or what it does by being able to read a descriptive function name versus complex domain related boolean math which they may not care to know the intricate details of.
A good book about commonly considered best practices in Java for code organization is a book called Clean Code. It's a pretty easy and enjoyable read, I would suggest it.
This is referred to as functional decomposition, and (in my opinion) is always good practice.
Not only is it easier to read, you can find problems in that code easier, since you can now easily test each section individually.
For example, you can now make sure isEven actually returns an even number. If a problem arises later on, you know that method is not the issue. This is called unit testing.
I suggest switching
if(isEven(n)) {
} else {
if(isPrime(n)) {
}
}
to
if(isEven(n)) {
} else if(isPrime(n)) {
}
Since it gives the same functionality, yet saves you a line.
Although, if you were counting 0 as being even, you wouldn't even need isPrime; if it's not even, it has to be prime. You wouldn't need to perform all the processing in isPrime:
if(isEven(n)) {
System.out.println("Even");
} else {
System.out.println("Odd");
}
To make it a bit cleaner:
String result = isEven(n) ? "Even" : "Odd";
System.out.println(result);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Problem in infix to postfix conversion
at the point when value fetched is '-' then the compiler does not enter at else-if block (last case)
package com.conversion;
import java.util.Scanner;
public class mainclass {
private static Scanner sc;
public static void main(String[] args) {
// TODO Auto-generated method stub
String s;
sc = new Scanner(System.in);
System.out.println("Enter a complete expresion");
s= sc.next();
stackop ob = new stackop();
System.out.println("YOUR PROVIDED input expression is :"+s);
//System.out.print(" Equivalent postfix notation is : ");
System.out.println("\n\n");
ob.postfix(s);
}
}
class stackop{
char stack1[]=new char[50];
int top;
void push(char ch)
{
top++;
stack1[top]=ch;
System.out.println(" element pushed is: "+ch);
System.out.println("----- current value of top is after push overs : "+top+" -------");
}
char pop(){
char ch;
ch= stack1[top];
//System.out.println("current value of top is : "+top);
System.out.println(" element popped is: "+ch);
--top;
System.out.println("----- current value of top is after pop overs : "+top+" -------");
return ch;
}
boolean isalpha(char a)
{
if((a>='a' && a<='z')||(a>=0 && a<=9))
return true;
else
return false;
}
boolean operator(char ch)
{
if(ch=='/'||ch=='*'||ch=='+'||ch=='-')
return true;
else
return false;
}
int prech(char ch){
switch(ch)
{
case '-': return 1;
//break;
case '+': return 1;
//break;
case '/': return 2;
//break;
case '*': return 2;
}
return 0;
}
void postfix(String str)
{
char otop=0;
char[] output = new char[str.length()+1];
for(int i=0 ; i<str.length();i++)
{
char ch=str.charAt(i);
System.out.println("==========value fetched is "+ch+" ===========");
if(ch=='(')
push(ch);
else if(isalpha(ch))
{
System.out.println("elemnt inserted in output list is :"+ch);
output[++otop]=ch;
}
else if(ch == ')' )
{
char temp=0;
System.out.println(" a close bracket is encounterd ");
while((temp=pop())!='(')
{
output[++otop]=temp;
System.out.println("elemnt inserted in output list is :"+temp);
}
}
else if(operator(ch))
{
if(prech(stack1[top])==0||(prech(stack1[top])<=prech(ch))||(prech(stack1[top])=='('))
push(ch);
}
else if(prech(stack1[top]) > prech(ch))
{
System.out.println(" hahah here i come");
output[++otop]=pop();
push(ch);
}
}
while(top>0)
{
output[++otop]=pop();
System.out.println("elemnt inserted in output list is :"+output[otop]);
}
System.out.println("\n\nOUTPUT OF EXPRESSION IS : " );
for(int j=0;j<str.length();j++)
{
System.out.print(""+output[j]);
}
}
}
In this chunk of code:
else if(operator(ch))
{
if(prech(stack1[top])==0||(prech(stack1[top])<=prech(ch))||(prech(stack1[top])=='('))
push(ch);
}
else if(prech(stack1[top]) > prech(ch))
The operator(ch) method returns true for your operators, which means control flow never reaches the second else if. What you probably want to do is move it inside the first else if, as shown below:
else if(operator(ch))
{
if(prech(stack1[top])==0||(prech(stack1[top])<=prech(ch))||(prech(stack1[top])=='('))
{
push(ch);
}
else if(prech(stack1[top]) > prech(ch)) { ... }
}
The title and the question do not have anything in common, also you should format your code. Nonetheless here's my answer to the question which you probably would've asked had you written an appropriate title.
Well actually 0 != '0' in programming, because '0' is translated to it's integer value which in ASCII is 48 and the comparison is between 0 and 48.
So your isalpha method should look like this:
boolean isalpha(char a)
{
if((a>='a' && a<='z')||(a>='0' && a<='9'))
return true;
else
return false;
}
Also, there are these neat little methods with which you don't need to check characters' ASCII code to compare them. I personally prefer this approachh as it is more simple and concise. It would look like this:
boolean isalpha(char a)
{
return Character.isDigit(a) || Character.isAlphabetic(a);
}