what can cause this particular palindrome a logic error - java

The following method was written to determine whether its String parameter reads identically left-to-right and right-to-left (the so called palindrome). I am having trouble finding the logic error of this palindrome. I believe the error is that the two conditions in the whole loop can affect checking the characters in the string. Please correct me if I am wrong so I can propose a proper solution.
This may be a stupid question to many of you, but I am new to java programming and this is written question on paper not actual code if that makes sense.

Your logic will only work if the length of input string is an odd number, i.e. 1,3,5 etc.
Because in case the length is even, i will never be equal to j. Example for a string "abba":
while (i == j && S.charAt(i) == S.charAt(j)) { // i = 0, j = 3
i++;
j--;
}
iteration-2:
while (i <= j && S.charAt(i) == S.charAt(j)) { // i = 1 , j = 2
i++;
j--;
}
iteration-3:
while (i <= j && S.charAt(i) == S.charAt(j)) { // i = 2 , j = 1
i++;
j--;
}
This will finally result in StringIndexOutOfBoundsException when i reaches negative value and j reaches a value greater than length of string.
Try below code:
static boolean isPalidrome(String s) {
int i = 0;
int j = s.length() - 1;
while( i <= j && s.charAt(i) == s.charAt(j)) {
i ++;
j--;
}
return i >= j;
}

your code will fail if input string is something like "zz" or "xxxx" meaning even length with same characters so ideally you can try with something like this :
public static boolean isPal(String str) {
int start = 0;
int end = str.length() - 1;
while (start < end) {
final char f = str.charAt(start++);
final char b = str.charAt(end--);
if (f != b) {
return false;
}
}
return true;
}

You may apply following changes in your own code. There are basically two changes which are in your termination condition of while loop i.e. i <= j and return condition of (i >= j)
public static boolean isPalindrome(String S) {
int i = 0, j = S.length() - 1;
while (i <= j && S.charAt(i) == S.charAt(j)) {
i++;
j--;
}
return (i >= j);
}

Related

Leetcode 9. Palindrome Number

I am trying to do this converting the integer to a string.
Inside the if clause, if I used s.charAt(i) == s.charAt(j) first then i++, j--, I couldn't pass the test of input = 121, I got false instead of true. But if I put s.charAt(i) != s.charAt(j) first, then accepted.
Wrong answer:
class Solution {
public boolean isPalindrome(int x) {
String s = String.valueOf(x); //n
int l = s.length();
int i = 0;
int j = l - 1;
while (i <= j) {
if (s.charAt(i) == s.charAt(j)) {
i++;
j--;
}
return false;
}
return true;
}
Accepted answer:
class Solution {
public boolean isPalindrome(int x) {
String s = String.valueOf(x); //n
int l = s.length();
int i = 0;
int j = l - 1;
while (i <= j) {
if (s.charAt(i) != s.charAt(j)) {
return false;
}
i++;
j--;
}
return true;
}
}
What did I miss?
The wrong solution returns false in any case and the correct solution only returns false when s.charAt(i) != s.charAt(j) is true.
If you want to skip return false; in the first code, you either need to move it into an else clause or use continue; in the if clause in order to directly jump to the next loop iteration.

Printing only NON-BOUNDARY and CORNER elements of an (n*n) array

I am to write a program that prints ONLY the NON-BOUNDARY AND CORNER elements of an (n*n) array, for my assignment, and this is the main part of the code:
The output I am getting is this:
As you can see, the non-boundary elements (6,7,10,11) are not in their correct positions, which I believe, is because of incorrect printing of tab spaces within the loop. (My code is totally a mess) I would like some help or suggestions to fix this. Thanks!
I generally find that flattening things (the if-conditions in particular), and putting conditions into boolean-returning methods helps. Try something like
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++ {
if (isCorner(i,j,n) || !isEdge(i,j,n)) {
//...
} else {
//...
}
}
System.out.println();
}
where isCorner(i,j,n) and isEdge(i,j,n) are defined something like
public boolean isCorner(int row, int column, int gridSize) {
//...
}
A you got a solution, just missing spaces, I'll add some smart things:
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
boolean visible = (i % (n - 1) == 0) == (j % (n - 1) == 0);
if (visible) {
System.out.printf(" %4d", a[i][j]);
} else {
System.out.print(" ");
}
}
System.out.println();
}
No longer any problems with tabs "\t", though I used spaces here.
Keep it simple, too many cases just cause problems - as you experienced.
The trick here is to consider whether to print or not. Hence I started with
a variable visible.
The border condition
i == 0 || i == n - 1
could also be written with modulo as
i % (n - 1) == 0
If this is "too smart", hard to grasp reading:
boolean iOnBorder = i % (n - 1) == 0;
boolean jOnBorder = j % (n - 1) == 0;
boolean visible = iOnBorder == jOnBorder;
The "X" pattern checks the _equivalence of i-on-border and j-on-border.
For the rest: formatted printf allows padding of a number.
Try this i have optimized your if condition
No need to again check for i == 0 or i == n-1
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==0 || i==n-1){
if(j==0 || j==n-1){
System.out.print(a[i][j]);
}
}else{
if(j != 0 && j!= n-1){
System.out.print(a[i][j]);
}
}
System.out.print("\t");
}
System.out.println();
}
Just gave a try in case you might find it helpful.
public static void main(String[] args) throws ParseException {
int[][] ar = new int[4][4];
int[] input = new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int pointer=0;
int imin=0,jmin=0,imax=3,jmax=3;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
ar[i][j]=input[pointer];
pointer++;
}
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(!((i==imax && j==jmin)||(i==imin && j==jmax)||i==j) && //For skipping the corners
(i == imin || j == jmin || i == imax || j == jmax)){// Not to print the borders
continue;
}
else {
System.out.println(ar[i][j]);
}
}
}
}

What's the effect of changing this condition in this Java function to find palindromes?

I am wondering how changing this condition will change the way the function works:
public static boolean palindrome(String str) {
int i = 0;
int j = str.length() - 1;
while(i < j) { // This condition
if(str.charAt(i) != str.charAt(j)) {
return false;
}
i = i + 1;
j = j - 1;
}
return true;
}
Changing it as follows:
public static boolean palindrome(String str) {
int i = 0;
int j = str.length() - 1;
while(i <= j) { // Change is here
if(str.charAt(i) != str.charAt(j)) {
return false;
}
i = i + 1;
j = j - 1;
}
return true;
}
They seem to both detect palindromes. The second one takes one more step. I don't see how this changes anything.
Thank you!
Between while(i < j) and while(i <= j) The difference is that the second one has one additional step because in the end, you are comparing i with j as suppose just everything less than j
Example with input abcba:
// First Code Indices Checked (i and j)
0 < 4
1 < 3
2 < 2 //fails, done
// Second Code Indices Checked (i and j)
0 <= 4
1 <= 3
2 <= 2 //passes, continues
3 <= 1 //fails, done, unneeded comparison
And just like #azurefrog said : "You don't have to check past the
midpoint in palindrome detection"

Check if a character appears more than once in a string using charAt() and loop

The code is giving characters for consecutive appearances and not for non-consecutive repetition of a character in a string. Using function can be easy but I want to use loop and use charAt in it to compare.
int count = 0;
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)==str.charAt(i+1)) {
count++;
}
return count;
}
Your code will throw IndexOutOfBoundsException.
You need a nested loop, because now you're checking if there are two adjacency equal characters.
Do something like that (I won't show you a solution, but I'll guide you):
for (int i = 0; i < str.length() - 1; i++) {
another loop with index j {
if(str.charAt(i)==str.charAt(j)){
count++;
}
}
}
However, as suggested in comments by #BrianRoach, if you use a Map, you'll get a better solution:
You can have a Character key and a value of Integer that indicates how many times a char appears in the String.
Edit:
After your edit, you only need to change the loop condition to str.length() - 1.
try
int count = 0;
for (int i = 0; i < str.length() - 1; i++) {
for (int j = i + 1; j < str.length; j++) {
if(str.charAt(i)==str.charAt(j)){
count++;
}
}
return count;
}
I know this is late in time, but rather than complex responses I came up with this:
public static boolean isitIsogram(String word){
int count = 0;
char check = ' ';
if(word == "" || word == null){
return false;
}
String newWord = word.toLowerCase();
char [] checkWord = newWord.toCharArray();
for (char i : checkWord){
if(check == i)
return false;
for(char j : checkWord){
if(i == j){
count++;
if(count > 1){
check = i;
}
}
}count = 0;
}
return true;
}
This function would also cater for empty and null string cases

Why does this result in a infinite loop?

I am trying to program a method that will use Gauss Elimination on a matrix (2 dimensional array), and I'm trying to debug my method and I've encountered this problem
public int Gauss() {
int i = 1;
int j = 1;
int pivotCol = 0;
while (pivotCol == 0 && j <= cols())
if (i == rows()){
j ++;
i = 1;
}
if (get(i,j) == 1.0){
pivotCol = j;
} else {
i ++;
}
return pivotCol;
}
This is not the final method, but for some reason, this loop never ceases, why?
while (pivotCol == 0 && j <= cols()) {
...
}
You forgot the brackets, so the while is only working with the if statement and therefore its running infinite.
I guess the problem is that your while loop doesn't have curly braces, e.g. it's effectively as follows:
while (pivotCol == 0 && j <= cols()) {
if (i == rows()){
j++;
i = 1;
}
}
If i != rows() this will never terminate.

Categories

Resources