Comparing the values of two arrays using recursion? - java

I am trying to check if two arrays have the same length, and the same values in the same exact position.
My current code looks like this:
public class MyArray {
private int size;
private int[] array;
private boolean isSorted; //to check if array is sorted
private static int arrCount; //used to identify which MyArray object
public MyArray(){
size = 10;
array = new int[10];
arrCount+=1;
}
public MyArray(int Size){
size = Size;
array = new int[Size];
arrCount+=1;
}
public MyArray(MyArray arrOther){
this.size = arrOther.getSize();
this.array = arrOther.getArray();
arrCount+=1;
}
public int getSize(){
return size;
}
public int[] getArray(){
return array;
}
#Override
public boolean equals(Object other){
if (other instanceof MyArray){
MyArray second = (MyArray) other;
if (second.getSize() == this.getSize())
return equalsHelper(this.getArray(), second.getArray(), 0, (size-1));
}
//else
return false;
}
private boolean equalsHelper(int[] first, int[] second, int iStart, int iEnd) {
if (iStart == iEnd) {
return true;
}
if (first[iStart] == second[iStart]) {
if (equalsHelper(first, second, (iStart + 1), iEnd)) {
return true;
}
}
return false;
}
}//end class
for some reason it always returns true even if the arrays are in different order.
the equals method is called in the main program here:
--main method--
if (MA2.equals(MA1)) //the arrays are identical here
{
System.out.println("The first and second arrays are equal.");
}
else {System.out.println("The first and second arrays are NOT equal.");}
MA2.sort(); //the order of the elements changes
System.out.println("The second array has been sorted in ascending order.");
if (MA2.equals(MA1))
{
System.out.println("The first and second arrays are equal.");
}
else {System.out.println("The first and second arrays are NOT equal.");}

First check (preferably) outside of your helper should be to see if both the arrays have equal lengths. Makes no sense to continue otherwise.
equalsHelper should return true if end of array is reached.
I see no reason to have 2 separate pointers for index since the arrays are required to be of the same size and the same index is being checked.
Invocation:
....
....
if(first.length != second.length)
return false;
return equalsHelper(first, second, 0);
The helper method...
private boolean equalsHelper(int[] first, int[] second, int indx) {
if(indx == first.length)
return true;
if(first[indx] != second[indx)
return false;
return equalsHelper(first, second, indx+1);
}

Firstly, iStart and iEnd are redundant. use .length
String[] array = new String[10];
int size = array.length;
If you're trying to compare contents of arrays that may be identical, you need to pass through it manually.
for(int i = 0: (i > first.length || i > second.length; i++){
if(first[i] != second[i]){
return false;
}
}
return true
Your next problem is
if (iStart == iEnd){
return first[iEnd] == second[iEnd]; //return true or false
Your logic here is wrong. You can't directly compare arrays like this. It's comparing the memory address. This will always be false unless you pass through the exact same array when the method is called - which i don't think is what you're trying to do
Array lengths are set manually, so it's a conscious effort to get a difference.
Let me suggest using an ArrayList if you're expecting differing lengths. They're also more flexible.
ArrayList <Integer> a = new ArrayList <int>();
ArrayList <Integer> b = new ArrayList <int>();
Then you'll need to check their lengths. ArrayList uses the .length() method instead of an Array[].length property
if(a.length() == b.length()){
then if you want to see if each value in each index is identical, you'll need to pass through the array manually as shown above.

Related

How would I check if all elements in an array are present in another array with no duplicates?

Run into abit of trouple with my code, want to check if sharedMemory is present in entire deck(it is) and have no duplicates of an object. I am getting false with this code and I don't really know why, any help would be appreciated. rank and suit together form a card object. rank and card are enumerators with values. Note: when i use 'return Arrays.asList(entireDeck).containsAll(sharedMemory)' on its own it does show true, but the messy if part is trying to check for duplicates
public static boolean isFull(){
Card[] entireDeck = Deck.fillDeck();
sharedMemory =Arrays.asList(Deck.fillDeck());
int i=0,duplicates=0, position =0, original;
for(Card c:entireDeck){
Card f = new Card(c.rank, c.suit);
original=i;
if (f.rank.equals(sharedMemory.get(i).rank)&&f.suit.equals(sharedMemory.get(i).suit)){
duplicates+=1;
position=i;
for(i=0; i<position;i++) {
if (f.rank.equals(sharedMemory.get(i).rank)&&f.suit.equals(sharedMemory.get(i).suit))
{
duplicates += 1;
return false;
}
}
for (i=position+1; i<52; i++){
if (f.rank.equals(sharedMemory.get(i).rank)&&f.suit.equals(sharedMemory.get(i).suit))
{
duplicates += 1;
return false;
}
}
if(duplicates>1){
return false;
}
else{
i=original;
}
}
i=original;
i++;
}
return Arrays.asList(entireDeck).containsAll(sharedMemory);
}
Thanks :)
The easiest way is to use a Set<Card>. If the return value of adding an object to a set is false, then it means the set already contains it, thus a duplicate. For this to work the Card class must override both hashCode and equals.
Set<Card> set = new HashSet<>();
for(Card card : cardArray) {
if (!set.add(card)) { // if false then !false is true so signal duplicate.
System.out.println("Duplicate of " + card + " found);
break;
}
}
You can always sort the Cards and then do a one to one comparison to see if they are equal. Comparing adjacent cards of a sorted deck can also detect duplicates.
Here is one example of how this could be achieved using an integer array. For your use case you would want to implement a Comparator for sorting and ordering.
I decided to show an approach which modify the input arrays during the check (by sorting them each run). This allows for moderate performance improvements, however I doubt that your use case will be using a large enough dataset for it to be a consideration.
// Checks if a is a subset of b and does not contain duplicates
public static boolean subsetOf(int[] a, int[] b) {
Arrays.sort(a);
Arrays.sort(b);
int aIdx = 0;
int bIdx = 0;
while (aIdx < a.length && bIdx < b.length) {
if (a[aIdx] == b[bIdx]) {
aIdx++;
bIdx++;
// Check for duplicate when incrementing index
if (aIdx + 1 < a.length && a[aIdx] == a[aIdx + 1]) {
return false;
}
} else if (b[bIdx] < a[aIdx]) {
// We need to keep moving through b to find next a
bIdx++;
} else {
// We missed an element in a
return false;
}
}
// Verify that we found all elements in a
return aIdx == a.length;
}
For your use case, I would recommend something like this for readability.
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
public static boolean subsetOf(Card[] a, Card[] b) {
Set<Card> aSet = new Hashset<>();
Set<Card> bSet = new Hashset<>();
aSet.addAll(Arrays.asList(a));
bSet.addAll(Arrays.asList(b));
return aSet.size() == a.length && bSet.containsAll(aSet);
}
In order to use this method, make sure to implement hashCode and equals in Card. You don't need to do anything fancy or import any extra libraries. The important part is that it returns a different number for every rank/suit combination.
public class Card {
// Gives a unique number for each card
#Override
public int hashCode() {
return 4 * rank + suitNum;
}
// Check if this card is the same as another object
#Override
public boolean equals(Object other) {
if (other instanceof Card) {
Card otherCard = (Card) other;
return rank == otherCard.rank && suitNum == otherCard.suitNum;
}
return false;
}
}

array required but [ClassName] found java

I'm trying to write a function checking if 2 arrays are equal.
public class DynamicArray {
private int size; // stores the number of “occupied” elements in the array
private int[] array;
...
boolean equals(DynamicArray obj) {
boolean keepChecking = true;
int objSize = 1;
for (int i = 0; i < obj.length; i++) {
if (obj[i] == 0 && keepChecking) {
keepChecking = false;
objSize = obj[i];
}
}
if (size != objSize)
return false;
for (int i = 0; i < size; i++) {
if (array [i] != obj [i]) {
return false;
}
}
return true;
}
}
The thing is that array might be partially filled array, not filled elements will be just zeros. So, to check if 2 arrays are equal, first, I find the size of the occupied array and then I do all the checkings.
So, every time I'm trying to get the value of obj[i] or obj.length it keeps showing the error "array required, but DynamicArray found." for obj[i] and "cannot find symbol \n symbol: variable length \n location: variable obj of type DynamicArray" which I don't understand because the other array is also DynamicArray type
public class ArrayDemo {
public static void main(String[] args) {
DynamicArray ar1 = new DynamicArray(1);
DynamicArray ar2 = new DynamicArray(1);
System.out.println("equals() is " + ar1.equals(ar2));
}
}
Your parameter obj in the equals method is not an array but an instance of DynamicArray. Therefore you cannot access the values with the [] on the identifier obj. You need to rewrite that method. You also need to include methods for setting and getting the elements of the array in your DynamicArray object. For example:
val = ar1.get(0);
and
ar1.set(0, value);
So this means your Dynamic array needs the following two methods (I am assuming the values of your array are ints, but this could be anything). I'll let you figure out what goes in them as I see you must be learning the language.
public void set(int index, int value){
}
public int get(int index){
}
That way you can then use your methods in your rewritten equals function to access the elements of the array.
Another tip. You would be better sorting both arrays. Compare the first element or each, then the next, and then the next until such time you find a mismatch. At that point you can return false. If you find no mismatch return true.
The thing is , DynamicArray is not an array, its a class, you have to define a length function of it.you can just call obj.length wich is DynamicArray class which has no method length

Insert elements into array in sorted order

I have written this code for insert and remove elements into and from array. But I want to insert elements into array in sorted order. How can I improve my "add" method? And I also don't know the implementation of the "remove" method. How can I implement remove method
public void add(int index, String str) {
// First make sure the index is valid.
if (index > elements || index < 0) {
throw new IndexOutOfBoundsException();
}
// If the list is full, resize it.
if (elements == list.length) {
resize();
}
// Shift the elements starting at index
// to the right one position.
for (int index2 = elements; index2 > index; index2--) {
list[index2] = list[index2 - 1];
}
// Add the new element at index.
list[index] = str;
// Adjust the number of elements.
elements++;
}
public boolean remove(String str) {
return false;
}
After filling the array, call:
Arrays.sort(array)
You are resizing the array, why dont you simply use a List?
List<Type> list = new ArrayList<Type>();
Collections.sort(list);
I suppose you should sort array not on adding element but when you return it. For decreasing array accesses you may use flag that will indicate that array must be resorted, i.e.
private boolean hasNew = false;
public void add (int index, String str) {
// Your code
hasNew = true;
}
public int[] getArray() {
if (hasNew) Arrays.sort(list);
return list;
}
This is the general idea, but feel free to adopt it.

issue with Arrays.asList()

I have a very simple program and I just need to check an array for a value in it.
I have a class called bulkBean. this is it.
public class bulkBean {
private int installmentNo;
private double amount;
public int getInstallmentNo() {
return installmentNo;
}
public void setInstallmentNo(int installmentNo) {
this.installmentNo = installmentNo;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
}
Now I have an array of this bulkBean type in my program, this is my program.
import java.util.Arrays;
public class test {
public static boolean scan_bulkList(bulkBean[] bulkList, int i) {
int[] arr = new int[bulkList.length];
for(int x=0;x<bulkList.length;x++){
arr[x] = bulkList[x].getInstallmentNo();
}
for(int j = 0; j< arr.length ;j++){
System.out.println("INFO: array "+j+" = "+arr[j]);
}
if (Arrays.asList(arr).contains(i) == true) {
return true;
} else {
return false;
}
}
public static void main(String[] arg){
bulkBean bb1 = new bulkBean();
bb1.setInstallmentNo(1);
bb1.setAmount(5500);
bulkBean bb2 = new bulkBean();
bb2.setInstallmentNo(2);
bb2.setAmount(4520);
bulkBean[] bulkArray = new bulkBean[2];
bulkArray[0] = bb1;
bulkArray[1] = bb2;
boolean a = scan_bulkList(bulkArray,1);
System.out.println("val = "+a);
}
}
I create 2 instances of bulk bean and I set values to them. Then I added those two instances to an array. Then I pass that array to the method to check for a value(also given as a parameter. In this case it is 1.). If the array contains that value, it should return true, otherwise false.
whatever value I enter, it return false.
Why do I get this issue?
Arrays.asList() returns a List which has a single element - an array. So, you are actually comparing against an array. You need to compare against each value in the array.
As TheListMind told, Arrays.asList() taken on an int[] gives you a list containing the array.
Personally, I would construct directly the List instead of constructing the array, or even better (no need of array instanciation), test while iterating the bulk array :
for(int x=0;x<bulkList.length;x++){
if (bulkList[x].getInstallmentNo() == i){
return true;
}
}
return false;
The mistake you made here is , you created the int array which must be Integer array because Arrays.asList().contains(Object o); makes the input parameter also Integer(Integer i). int is not an object Integer is the object. Hope it will work.
int[] arr = new int[bulkList.length];
change to:
Integer[] arr = new Integer[bulkList.length];
Change the method as below to avoid complications:
public static boolean scan_bulkList(bulkBean[] bulkList, int i) {
int[] arr = new int[bulkList.length];
for(int x=0;x<bulkList.length;x++){
arr[x] = bulkList[x].getInstallmentNo();
if (bulkList[x].getInstallmentNo()==i) {
return true;
}
}
return false;
}

Compare one element from multiple 2D arrays (java)

I have multiple 2D arrays of Strings that are layed out a little like this
Array 1
[0] = ["01/01/01","Bill","17","0.86"]
[1] = ["02/01/01","Bill","12","0.84"]
[2] = ["03/01/01","Bill","15","0.85"]
Array 2
[0] = ["01/01/01","Joe","14","0.81"]
[1] = ["02/01/01","Joe","15","0.83"]
[2] = ["04/01/01","Joe","19","0.85"]
I'm trying to compare only data from the same days, so what I need to do is search both arrays for dates that are in one but not the other and then remove them. So in the above example I would remove [2] from both of the arrays. Is there a way of doing this using List/Collection retainAll or will I have to write a loop? Oh I'm using Java.
There is no direct way of removing items using collection. But if both the arrays are sorted by date, you would be able to compare the data without removing the missing dates from each of the array.
Well, I don't prefer using arrays for this problem. Removing elements from array is a bad idea. You might try linked list. Something like this
for (int i=0; i < array1List.size(); i++) {
String date = array1List.get(i)[0];
int index = -1;
for(int j=0; j < array2List.size(); j++) {
if array2List.get(j)[0].equals(date)) {
index = j;
break;
}
if(index >= 0) array2List.remove(j);
}
}
To use a Collection to do this you will have to put each array entry into an object. Something like:
class DayInfo {
String date;
String name;
...
public DayInfo(String[] arrayData) {
this.date = arrayData[0];
this.name = arrayData[1];
...
}
#Override
public boolean equals(Object obj) {
if (!(obj instanceof DayInfo))
return false;
if (date == null) {
return ((DayInfo)obj).date == null;
} else {
return date.equals((DayInfo)obj).date);
}
}
#Override
public int hashCode() {
if (date == null)
return 0;
else
return date.hashCode();
}
}
Then if you load both of your arrays into DateInfo collections:
Set<DayInfo> dayInfos1 = new HashSet<DayInfo>(array1.length);
for (String[] arrayEntry : array1)
dayInfos1.add(new DayInfo(arrayEntry));
Set<DayInfo> dayInfos2 = new HashSet<DayInfo>(array2.length);
for (String[] arrayEntry : array2)
dayInfos2.add(new DayInfo(arrayEntry));
Now you can use the retainAll in both directions:
// remove everything from set #1 that doesn't have a date in set #2
dayInfos1.retainAll(dayInfos2);
// remove everything from set #2 that doesn't have a date in set #1
dayInfos2.retainAll(dayInfos1);
I think that would work.

Categories