Find if Entered Password is valid or not? - java

This is an interview question. I think the code below, works a bit and has some errors. The problem is as follows -
In 1-9 keypad one key is not working. If some one enters a password then not working key will not be entered. You have given expected password and entered password. Check that entered password is valid or not
Ex: entered 164, expected 18684 (you need to take care as when u enter 18684 and 164 only both will be taken as 164 input)
The code which does above is below.
public static void main(String[] args){
System.out.println(IsAMatch("164","18684"));
}
static boolean IsAMatch(String actual, String expected)
{
char faultyKey = '\0';
int i = 0, j = 0;
for(; i < expected.length() && j < actual.length(); ++i)
{
if(actual.charAt(j) != expected.charAt(i))
{
if('\0' != faultyKey){
if(faultyKey != expected.charAt(i))
return false;
}
else{
faultyKey = expected.charAt(i);
}
}
else{
++j;
}
}
System.out.println("FaultyKey= "+faultyKey);
return (i == expected.length() - 1 && j == actual.length() - 1)? true : false;
}
It is detecting the faulty key correctly (Ex here it is 8), but giving wrong output (As False) Even though the test case used above should give true.
Any suggestions to fix this? If any better method/ideas are most appreciated.

Change the return statement to:
return (i == expected.length() && j == actual.length())? true : false;
The bug is that i and j are both increased first and then checked if they meet the loop condition. Obviously both i and j fail to meet the condition as the control flow breaks out from the loop. Therefore, i and j are exactly equal to expected and actual length respectively.
Moreover, the expression in your return statement is gratuitous. You could just return true at that point of the program as it is a tautology at that stage. I.e. there is no way that you can be at that point in your code and your expression evaluates to false.

static boolean IsAMatch(String actual, String expected) {
char faultyKey = '\0';
int i = 0, j = 0;
for (; i < expected.length(); ++i) {
if (j >= actual.length() || actual.charAt(j) != expected.charAt(i)) {
if ('\0' != faultyKey) {
if (faultyKey != expected.charAt(i)) {
return false;
}
} else {
faultyKey = expected.charAt(i);
}
} else {
++j;
}
}
System.out.println("FaultyKey= " + faultyKey);
return (i == expected.length() && j == actual.length()) ? true : false;
}
Consider the following condition
System.out.println(IsAMatch("164", "186848"));
Your logic will not work, because before i meets the length j would meet the actual length.
you dont need to have condition j < actual.length in for loop.

Your return statement should be :
return (i == expected.length() && j == actual.length()) ? true : false;
or, simpler :
return (i == expected.length() && j == actual.length());
because i and j reach the length of the strings when the loop ends.

The issue is with these two statements:
i == expected.length() - 1
j == actual.length() - 1
Remove the - 1 by each of them and it should work fine.

Related

Brute force: count number of sub strings in a string array

What I am supposed to do is create an algorithm that counts the number of substrings in a piece of text where the substrings can be the letter B followed by C or C followed by B. I'm not sure what to do, but I tried it and came up with the result below. I'd like to know if I did it correctly.
int substrCount(String S[0...n-1]){
int count = 0;
for (int i = 0; i<=n-2; i++) {
for (int j=i+1; j<i+2; j++) {
if ((S[i] == 'B' && S[j] == 'C' ) || (S[i] == 'C' && S[j] == 'B')) {
count = count + 1;
}
}
}
}
I am gonna ignore whether it includes lowercase or uppercase for now. I also need to find the complexity of the algorithm from which I believe it is O(n^(2)). Did I do this correctly? If so, can I make it any more efficient?
This works well for me
static int substrCount( String str) {
int count=0;
for (int i=0; i<str.length()-1; i++)
{
boolean bc = (str.charAt(i) == 'B' && str.charAt(i+1) == 'C');
boolean cb = (str.charAt(i) == 'C' && str.charAt(i+1) == 'B');
if (bc || cb) {
count++;
}
}
return count;
}
You need to loop the sequence of chars in string just once to get the desired result. Check the couple of chars if they are equal "BC" or "CB" and move one index forward to the end of the string.
Output example:
"ACBAA" gives result 1
"ABCBA" gives result 2
"BCBCB" gives result 4
"BBBBB" gives result 0

array index out of bounds not fired

public static void insertionSort(int[] data) {
for (int i =0; i < data.length; i++) {
int current = data[i];
int j = i-1;
while (j >=0 && data[j] >= current) {
data[j+1] = data[j];
j--;
}
data[j+1] = current;
}
}
the line while (j >=0 && data[j] >= current) should throw array index of bounds when data[-1] for the first time. I dont understand why it does not. Can some one please help
Thank you
Ashok Pappu
Boolean expressions like these are never fully evaluated if the condition can be met earlier.
So...in your case since j >= 0 is false and false && ??? will always be false the second part does not need to get evaluated. This is why data[-1] will never be called.
You can use the same principle for null checks, e.g.
if (object != null && object.isSomething())
If while clause contains more, than 1 expression, splitted by &&, they are executed one by one. This is done to increase performance.
I.e. at first in your code j >= 0 will checks. If j < 0, it false. So, cycle will be interrupted regardless of the 2nd expression.

My second for loop is not running?

I have 2 for loops, I am working on a 2048 like game. This method returns true if something slid to the left. However, it returns false to me and only "banana" is printing, which means the other for loop isn't even executed. What could be the case?
public boolean slideLeft(int[][] array, int row) {
int[] array2 = new int[array.length];
boolean result = false;
for(int j = 0; j < array.length; j++) {
array2[j] = array[j][row];
System.out.println("banana");
}
for (int i = 0; i <array2.length; i ++) {
if (array2[i] == 0 && array2[i+1] != 0 && i != array2.length-1) {
System.out.println("apple");
array2[i] = array2 [i+1];
result = true;
}
if(array2[i] != 0 && i != 0 && array2[i-1] == array2[i]) {
System.out.println("pear");
array2[i-1] = 2*(array2[i-1]);
array2[i]=0;
result = true;
}
}
return result;
}
Second for loop executed but none of condition inside the second for loop is not match. Then you will not get any out put.
You can make sure second for loop is running just put a else and print something.
You need to reconsider and rethink about condition inside the second for loop to correct them.
Your other for loop would throw ArrayIndexOutOfBoundsException when i==array2.length-1, because the following condition is evaluated from left to right, so array2[i+1] would be aveluated before i != array2.length-1 is evaluated.
if (array2[i] == 0 && array2[i+1] != 0 && i != array2.length-1) {
System.out.println("apple");
array2[i] = array2 [i+1];
result = true;
}
You should change it to :
if ( i != array2.length-1 & array2[i] == 0 && array2[i+1] != 0) {
System.out.println("apple");
array2[i] = array2 [i+1];
result = true;
}
Your second if condition avoids a similar exception, since you check that i != 0 before checking that array2[i-1] == array2[i].
Its seems that you are trying to create an array, array2, of integers of length array.length. There is a possibility that the array.length could just contain two rows (possibility of single row is eliminated because if there was just one row you would have seen IndexOutofBoundException) in such case your if conditions will never get executed.
A way you can work through is by placing check statements for array.length and else clause in the second for loop.

What is wrong with this method using an int[][]?

This method is supposed to return true if there is more than one 1 in a column of a 2D array, yet it doesn't work. I can't figure out what's wrong with it so I thought I'd get some expert opinions.
Example:
10010
01001
10100
will return true because there are 2 ones in the first column.
Here is the code
public static boolean isVert(int[][] x) { //checks for more than one 1 in columns
int count = 0;
boolean break2 = false;
boolean check = false; //false means no 2 (or more) queens in same column
for (int i = 0; i < x.length; i++) {
count = 0;
for (int j = 0; j < x[i].length; j++) {
if (x[i][j] == 1) {
count++;
}
if (count > 1) {
break2 = true;
check = true;
break;
}
}
if (break2) {
break;
}
}
return check;
}
You break at the first occurance of 1 in whole array, which is probably not the expected result.
Explanation of how your code works:
loop until counter i is less than length of array (number of rows in array)
loop until counter j is less than length of i-th row (number of columns or elements in array)
check if element on i-th row and j-th column is 1, if true, increase variable count by one
if count is greater than 1 (this means it has to be 2 or greater) set break2 and check to true, break
if break2 is true (which is as count is > 2 and first loop breaks), break this loop too:
this happens in 1st row of your example table
end of loops, return check (which is true because 1st row contains 2 ones)
The problem in your code is that you break when you find your first row that satisfies your condition, but you do not (necessarily) check all the rows in given array.
I have corrected the code for you, hopefully it works (untested)
public static boolean isVert(int[][] x) { //checks for more than one 1 in columns
int count = 0;
for (int i = 0; i < x.length; i++) {
int rowCount = 0;
for (int j = 0; j < x[i].length; j++) {
if (x[i][j] == 1) {
rowCount++;
}
if(rowCount > 1) {
count++;
break;
}
}
}
// returns true if count of lines containing 1 equals length of array,
// if not, returns false
return count == x.length;
}
Start of by improving your naming convention. Your code has many variables named by their contents, instead of named by how they are used. For example:
boolean check = false; // false means no two queens in the same column.
instead of
boolean twoQueensInColumn = false;
and the other example
boolean break2 = false;
instead of the more reasonable
boolean continueLooking = true;
Plus, it is a very good idea to avoid using variables as place holders for loop escaping logic. For example, the two stanzas
...
if (count > 1) {
break2 = true;
check = true;
break;
}
}
if (break2) {
break;
}
are a breeding ground for bugs, requiring a lot of debugging to ensure they work "right now" which will break just as soon as you modify the code. Much better would be
boolean keepLooking = false;
for (int row = 0; keepLooking && (row < board.length); row++) {
int queensInColumn = 0;
for (int column = 0; keepLooking && (column < board[row].length, column++) {
if (board[row][column] != 0) {
queensInColumn++;
}
if (queensInColumn > 1) {
keepLooking = false;
}
}
}
The main difference being the control logic is in the loop "conditional" block, where it belongs.
I would recommend turning your integers to string and using the .contains() method and looping through that. This would make the code easier to understand.

Why is my for-loop not functioning? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I'm making a program that counts the number of vowels in a phrase that was assigned by my teacher. To do this I have made a for-loop that in theory should check each character for being a, then e, the i, and so on before moving on to the next character. For some reason though nothing in the for-loop works. The build output states that everything is fine, but the for-statements aren't functioning properly. I know that t actually is the correct letter because I printed what t was but the for loop still won't work. What confuses me is the build output is fine, so it must be a logic error, but I can't find where it is. Here is the code:
for (i = 0; i != phrase.length(); i++) {
String t = phrase.substring(i, i + 1);
if (t == "a") {
count++;
System.out.println(count);
}
if (t == "e") {
count++;
}
if (t == "i") {
count++;
}
if (t == "o") {
count++;
}
if (t == "u") {
count++;
}
}
System.out.println(count);
Many thanks to anyone who can help me!
the exit condition is wrong, try:
for (i = 0 ; i < phrase.length(); i++) {
You have several issues in your code.
1) First issue being the i == phrase.length(). This is the until condition. Change this to i <= phrase.length(). *
In your case this would have worked but it's better to do it right. Normally you check on values here that could for example grow bigger than 10 and if you skip 10 and keep counting you would enter an infinite loop. So always use <= or >=.
*edit: Correction you should use < since you have a substring working with i+1.
2) Don't use == for String (or any other object) comparison. That will compare the memory address instead. For String use the equals() method.
Also make sure to put the known literal "a", "b" and so up front since you could get a nullpointer exception otherwise.
3) It might be better to go for a charAt(0) first and then use == since you can compare char (primitive) values.
4) I also combined the if statements in one.
String phrase = "WazzUp ? Who’s On FIRST??? IDUNNO";
phrase = phrase.toLowerCase();
System.out.println("value of phrase is: "+phrase);
int count = 0;
for (int i = 0 ; i < phrase.length() ; i++) {
String t = phrase.substring(i, i + 1);
if ("a".equals(t) || "e".equals(t) || "i".equals(t) || "o".equals(t) || "u".equals(t) ) {
count++;
}
}
System.out.println("value of count is: "+count);
Check the for exit condition and String comparison, which should be done using equal: if ("a".equals(t)) { ... }.
Your for-decleration is wrong.
It should be
for(<startexpression> ; <any expression, that is still true> ; in-/decrement>)
In your case you start with i=0, so on the same run i cannot equal phrase.length()in your case. This is why you code does not get executet.
Try:
for (i = 0 ; i < phrase.length(); i++) {
instead.
Also, when comparing string, you should use
String.equals("whatever")
instead of the equeals-operator (=).
In your for loop, shouldn't it be i = phrase.length() instead of i ==? i == is doing comparison instead of setting i equal to (i = sets it equal to something instead of comparing)
As to what emilioicai said your conditions is wrong
for (i = 0 ; i == phrase.length(); i++) { <----! Wrong
for (i = 0 ; i < phrase.length(); i++) { <---- Correct
Also strings Should be compared with equals, so instead of this
if (t == "a") {
count++;
System.out.println(count);
}
You should have this
if ("a".equals(t)) {
count++;
System.out.println(count);
}
And if you want to go fancy you can do something like this :)
String phrase = "WazzUp ? Who’s On FIRST??? IDUNNO";
phrase = phrase.toLowerCase();
System.out.println("value of phrase is: "+phrase);
int count = 0;
String[] characters = new String[] {"a", "e", "i", "o", "u"};
for (int i = 0 ; i < phrase.length() ; i++) {
String t = phrase.substring(i, i + 1);
for(String character : characters){
if(character.equals(t)){
count++;
}
}
}
System.out.println("value of count is: "+count);
The above makes code nicer, more scalable, and easier to read
There are two errors about your code.
First, for (i = 0 ; i < phrase.length(); i++) {}
Second, if (t .equals("a")) { but not if (t == "a") {
try this:
for (i = 0; i != phrase.length(); i++) {
String t = phrase.substring(i, i + 1);
System.out.println(t);
if (t.equals("a")) {
count++;
System.out.println(count);
}
if (t.equals("e")) {
count++;
}
if (t.equals("i")) {
count++;
}
if (t.equals("o")) {
count++;
}
if (t.equals("u")) {
count++;
}
}
by the way, it's more common to change your condition to this:
i < phrase.length()
since it shows the progress better and increases the readability of your code.
Make it this way
String phrase = "WazzUp ? Who’s On FIRST??? IDUNNO";
phrase = phrase.toLowerCase();
int count = 0;
int i = 0;
System.out.println(phrase);
for (i = 0 ; i < phrase.length(); i++) {
String t = phrase.substring(i, i + 1);
if (t == "a") {
count++;
System.out.println(count);
}
if (t == "e") {
count++;
}
if (t == "i") {
count++;
}
if (t == "o") {
count++;
}
if (t == "u") {
count++;
}
}
System.out.println(count);

Categories