CodingBat commonTwo method, help examine the output? - java

Question Summary:
Given two String arrays, return an integer representing how many matches are between them (ignore duplicates).
Real Answer:
http://www.javaproblems.com/2013/11/java-ap-1-commontwo-codingbat-solution.html
My Code
public int commonTwo(String[] a, String[] b) {
int count = 0;
boolean done = false;
for (int i = 0; i<a.length-1; i++){
if(a[i].equals(a[i+1])){
i++;
for (String j:b)
if (a[i].equals(j) && !done){
done = true;
count++;
}
}
else{
for (String j:b)
if(a[i].equals(j) && !done){
done = true;
count++;
}
}
done = false;
if(i == a.length-2)
for (String j:b)
if (a[i+1].equals(j) && !done){
done = true;
count++;
}
}
return count;
}
Image of output: [1]: http://i.stack.imgur.com/0esjC.png
So what it was intended to do was to go through all of the array a,if it equals the next one then go to that index, then add to count if there's a match between the arrays. The done boolean was used to make it so it doesn't add to count if there're duplicates of b that matches a and to end it once a match is found.
Lastly,
if(i == a.length-2)
was intended to make it so if it's the second before the last index number (as the last index number won't be checked in some cases), and not the same as the last index number, then it would check for matches for the last index number after checking the one before the last essentially. I understand why both errors occur and was wondering what could be done to fix it, particularly for the second one/comments on the code. Also, a third issue I notice would be (["a"], ["a"]) → 1 but the code will result in 0.

This question can be done is linear time O(N) that is a single traversal of both arrays a and b.
You should increment i as long as same string appears.So
if(a[i].equals(a[i+1]))
i++;
should be replaced by
while(i+1<a.length&&a[i].equals(a[i+1])){
i++;}
Also you do not need to go through entire array b for a single string of array a since both are in alphabetical order.You should only compare the string from the array b as long there is no match.Once a match is found then you should remember that index and next time matching should continue from that index onwards for the array b
Also you don't need the boolean variable done.
Keeping these things in mind the correct code is:
public static int commonTwo(String[] a, String[] b) {
int count = 0;
int j=0,i;
for (i = 0; i<a.length-1&&j<b.length-1;){
//SKIP DUPLICATES FOR ARRAY a
while(i+1<a.length&&a[i].equals(a[i+1])){
i++;}
//SKIP DUPLICATES FOR ARRAY b
while(j+1<b.length&&b[j].equals(b[j+1])){
j++;}
//MATCH THE STRINGS FROM ARRAY a AND ARRAY b
while(i<a.length&&j<b.length&&a[i].compareTo(b[j])!=0)
{
//INCREMENT I IF STRING IN ARRAY a IS LESS THAN STRING IN ARRAY b
if(a[i].compareTo(b[j])<0)
++i;
//INCREMENT J IF STRING IN ARRAY b IS LESS THAN STRING IN ARRAY a
else ++j;
}
//IF ABOVE LOOP BREAKS BECAUSE OF MATCH
if(i<a.length&&j<b.length)
{count++; ++j; ++i;}
}
//IF THE LAST ELEMENT OF ARRAY a IS LEFT FOR COMPARISON
if(i==a.length-1)
{
while(j<b.length)
{
//SKIP DUPLICATES OF ARRAY b
while(j+1<b.length&&b[j].equals(b[j+1]))
++j;
if(a[i].equals(b[j]))
{++count;}
++j;
}
}
//IF THE LAST ELEMENT OF ARRAY b IS LEFT FOR COMPARISON
if(j==b.length-1)
{
while(i<a.length)
{
//SKIP DUPLICATES OF ARRAY a
while(i+1<a.length&&a[i].equals(a[i+1]))
++j;
if(a[i].equals(b[j]))
++count;
++i;
}
}
return count;
}

This is the simplest solution i could come up with that uses only one loop.
public int commonTwo(String[] a, String[] b) {
int count = 0;
int i = 0;
int j = 0;
String s = "";
while (i < a.length && j < b.length) {
if (a[i].compareTo(b[j]) < 0)
i++;
else if (a[i].equals(b[j]) && a[i] != s) {
s = a[i];
count++;
i++;
j++;
}
else j++;
}
return count;
}

public int commonTwo(String[] a, String[] b) {
int ctr = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
if (i > 0 && a[i] == b[j] && a[i] != a[i - 1]) {
ctr++;
break;
} else if (i == 0 && a[i] == b[j]) {
ctr++;
break;
}
}
}
return ctr;
}

Related

Find first occurrence of an integer in a sorted list with duplicates

This code prints the first occurence of element 'k' in the array properly but the question I'm doing wants me to print -1 if the element 'k' is entirely not present in the array. I know its easy but I'm just stuck and its frustatiting any help?
n = sc.nextInt();
k = sc.nextInt();
int arr[] = new int[n];
for(int i=0;i<n;i++) {
arr[i] = sc.nextInt();
}
for(int i=0;i<n;i++) {
if(arr[i]==k) {
System.out.println(i);
break;
}
}
Use Arrays#binarySearch:
int firstIndexOf(int[] sortedArray, int x) {
int p = Arrays.binarySearch(sortedArray, x);
if (p < 0) {
return -1;
}
while (p > 0 && sortedArray[p - 1] == x) {
--p;
}
return p;
}
Binary search splits the searched range in half repetively looking in which half to continue. It returns either the found position or the complement (~p) of the insert position.
int findOccurenceOfElemet(int[] a, int k) {
if(a.length == 0) {
return -1;
}
for(int i = 0; i < a.length; i++) {
if(a[i] == k) {
return i;
}
}
//return -1 if element not found
return -1;
}
What you are asking in the title, and what you are asking in the post body, are two different questions; however, if we will follow your question's body, that has nothing to do with binary search, and introducing boolean flag would get you what you are asking for:
boolean notFound = true;
for(int i=0; i<n; i++) {
if(arr[i] == k) {
System.out.println(i);
notFound = false;
break;
}
}
if(notFound) System.out.println("-1");

unable to check all elements in array

private void clear() {
for (int i = 0; i<9; i++){
for (int j = 0; j<9; j++){
if(iseditable(i,j)){
bord[i][j].setText("");
}
}
}
}
private boolean iseditable(int i, int j) {
for (String s : generatedXY) {
char[] m = s.toCharArray();
char x = (char) (i + '0');
char y = (char) (j + '0');
return m[1] != x || m[3] != y;
}
return false;
}
I have used the following code in my app here generatedXY array contains all the points in the formate (i,j) as strings I want to extract i & j from the string and compare them with index of board but it is only checking the first element of generatedXY it is not all elements
First your for loops go from 0 to 8, I assume you wanted to write
i<=9 instead.
Second: For iterate over all elements of generatedXY, but you exit loop already in the first iteration by the return statement. You possibly wanted to write something like
if (m[1] != x || m[3] != y)
{
return true;
}
, then the return statement is only executed if the condition is true.

Program hangs and won't finish

I'm writing a program that is supposed to take as input, several arrays of objects, and process them with the output being all the elements that the lists have in common. In other words, find the intersection of three arrays.
When I attempt to run the program, it all goes fine until the program starts executing the while loop within findCommonElements(). It hangs there and doesn't step forward, and I can't figure out why. Any help would be greatly appreciated.
edit When the arrays are passed to this method, they are already sorted
public static Comparable[] findCommonElements(Comparable[][] collections)
{
team[] intersection = new team[50];
int index = 0;
int i = 0; //counter for collections[0]
int j = 0; //counter for collections[1]
int k = 0; //counter for collections[2]
System.out.print("test");
while (i < collections[0].length && j < collections[1].length && k < collections[2].length)
{
//if query value > collections[2] value, increment collections[2]
if (collections[0][i].compareTo(collections[1][j]) > 0)
{
j++;
incComparisons();
}
//if query value > collections[2] value, increment collections[2]
else if (collections[0][i].compareTo(collections[2][k]) > 0)
{
k++;
incComparisons();
}
else if (collections[0][i] == collections[1][j] && collections[0][i] == collections[2][k])
{
// add entry to intersection array
intersection[index] = (team) collections[0][i];
index++;
incComparisons();
// if the next item in each collection also matches, then add an extra instance of that item to the list
if (collections[1][j + 1] == collections[0][i] || collections[2][k + 1] == collections[0][i])
{
intersection[index] = (team) collections[0][i];
index++;
incComparisons();
}
i++;
j++;
k++;
}
}
return intersection;
}

What happens to a nested if statement in a for-loop if the conditions are not met and there is no else statement?

This is the code my prof gave on a practice exam. Since the first if statement has no else statement, does it exit the for-loop all together and move onto the next if statement? Then, if the second if-statement evaluates to true I'm assuming it's going to go through the first for-loop again and then the second. Once it starts goes through the second for-loop again does the loop begin at j=1 again or another value?
I'm also a little confused with what happens in the second if statement. Does it mean the value at what the currentMaxIndex is becomes the s[i] value and then the currentMax value?
Thanks!
public class Cards {
public static String[] sortCards(String[] s){ // SELECT SORT
for (int i = s.length - 1; i >= 1; i--){
// Find the maximum in the list[0..i]
String currentMax = s[0];
int currentMaxIndex = 0;
for (int j = 1; j <= i; j++) {
if (cardLessThan(currentMax,s[j])){
currentMax = s[j];
currentMaxIndex = j;
}
}
// Swap list[i] with s[currentMaxIndex] if necessary;
if (currentMaxIndex != i) {
s[currentMaxIndex] = s[i];
s[i] = currentMax;
}
}
return s;
}
static boolean cardLessThan(String s1, String s2){
char s1s = s1.charAt(s1.length()-1); //suites
char s2s = s2.charAt(s2.length()-1);
if(s1s < s2s)
return true;
else if(s1s > s2s)
return false;
// Same suite cards - order determined by card number
String n1 = s1.substring(0,s1.length()-1);
String n2 = s2.substring(0,s2.length()-1);
if(n1.equals("A") && !n2.equals("A")) return true;
if(n1.equals("2") && !n2.equals("A") && !n2.equals("2")) return true;
…
return false;
}
If the condition isn't met the loop continues onto the next iteration, and the condition is tested again. That inner loop could also have been written like,
for (int j = 1; j <= i; j++) {
if (!cardLessThan(currentMax,s[j])){
continue;
}
currentMax = s[j];
currentMaxIndex = j;
}

Comparing index 0 in array with all other indexes

If I want to compare index 0 with index 1, 2 and 3 for instance, how is that possible?
boolean iftrue = false;
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < i; j++) {
if (IntValue(array[j]) == IntValue(array[i + j])) {
iftrue = true;
}
}
}
return iftrue;
}
Just to put Sotirios' suggestion into code... Recall he suggested you save the first elem and compare other elements against it.
public boolean sameAsFirstElem(int[] array) {
boolean isEqual = false;
int firstElem = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] == firstElem) {
return true;
}
}
return isEqual;
}
Take 0th element is an variable and go on searching from 1st index onward. If you find the match stop else go all the way upto end of the array and report that match not found. This can be done in linear time O(N) where N is the size of the array. No need to have two loops and hence increase the time complexity to O(N^2)
boolean sameAsFirstElem(Object[] array) {
boolean isEqual = false; //Assume match will not be there, if we come across any,
// we will set it to true
int firstElement = IntValue(array[0]);
for (int i = 1; i < array.length; i++) {
if (IntValue(array[i]) == firstElement) {
isEqual = true; //Indicating that match has found
}
}
return isEqual;
}
I am assuming that IntValue(Object) return int, and hence the int firstElement, and taking Object as a parameter.

Categories

Resources