I have tried the following codes, but I'm still getting errors. It seems I have a problem in comparing two arrays, and checking if they point at one array. I also have a problem in swapping two arrays so that they can interchange their values. Additionally, removing values that are the same in an array seems to be so hard. The codes below is how I pictured them, but I'm still getting errors even after trying different approaches to the problems. Please help me understand how to compare two arrays, specifically on these codes.
public class ArraySwap {
public static void main(String[] args) {
//Some test code
ArraySwap swapper = new ArraySwap();
int[] a = {1, 2, 3}; //initialize array a[]
int[] b = a; //initialize array b[]
System.out.println(swapper.arrayEquals(a, b));
int[] arr = {1, 1, 2, 3, 4, 1, 5, 6, 8, 7, 9, 9, 8, 9, 1};
ArraySwap c = new ArraySwap();
arr = c.removeDuplicates(arr);
for (Integer i : arr) {
System.out.print(i);
}
System.out.println();
}
/*
Return true if the values in a are the same as the values in b
*/
public boolean arrayValuesEqual(int[] a, int[] b) {
if (Arrays.equals(a, b)) {
return true; //returning true
} else {
return false;
}
}
/*
Return true if a and b point to the same array
*/
public boolean arrayEquals(int[] a, int[] b) {
if (a.length == b.length) {
return true;
} else {
return false;
}
}
/*
* Swap a and b WITHOUT doing an elementwise copy.
*/
public void swap(int[] a, int[] b) {
int temp = a[0];
a[0] = b[0];
b[0] = temp;
}
}
/*
* Returns true if a and b have the same name
*/
public boolean sameName(Person a, Person b) {
if (a == b) {
return true;
} else {
return false;
}
}
/*
* Given an array of positive integers, removes duplicates
* in the array.
* #return a contiguous array with the remaining integers
* with a length equal to the number of remaining integers
*/
public int[] removeDuplicates(int[] integers) {
int[] toReturn = new int[];
for (int i = 0; i > integers.length; i++) {
if (i + 1 > integers.length) {
if (integers[i] == integers[i + 1]) {
remove.integers[i];
}
}
toReturn = integers[i];
}
return toReturn;
}
}
You seemed to have asked a few questions in one and it's not really clear what your goal is....
In your arrayValuesEqual() you're comparing arrays a & b with .equals this method is comparing a shallow copy of the arrays. If you want to do a deep copy you should use .deepEquals(). see more info here: comparing arrays in java
in your arrayEquals method the description reads if they point to the same array, but all you're doing is checking the length.. this does not prove that the contains are the same...
your swap method - will this work if it's a multidimensional array? What if they are not the same length array? You seem to be writing code for a specific case and not considering various test cases.
Your sameName method - that's not how you compare objects. the == compares object references, it checks to see if the two operands point to the same object (not equivalent objects, the same object). You will need to override an equals method for the Person object.
Related
I have written a method to compare different 2D Arrays and output whether they are the same or not using .equals. In my main tester class I am comparing two 2D Integer arrays to each other which are the same so the output should be 'true' and then two 2D String arrays which are different so the output should be false. When testing different combinations, when I test equal and unequal Integer arrays I get the correct output. Testing different size arrays, correct output and testing equal string arrays I get the correct output.
The issue I am having is the fact that when I test two unequal String arrays the program returns true when they are unequal so the output should be false. Thanks in advance for any help or tips.
public boolean equals(Object[][] other) {
boolean isEqual = false;
if (myArray.length != other.length) {
return isEqual;
}
for (int i = 0; i < myArray.length; i++) {
for (int j = 0; j < myArray[i].length; j++) {
if (myArray[i][j].equals(other[i][j])) {
isEqual = true;
} else {
isEqual = false;
}
}
}
return isEqual;
}
Testing:
public class TwoDTester {
public static void main(String[] args) {
//Initializing arrays
Integer[][] firstArray = {{2, 3}, {3, 4}, {4, 5}};
Integer[][] secondArray = {{2, 3}, {3, 4}, {4, 5}};
//Creating TwoDArray object for comparisons
TwoDArray first = new TwoDArray(firstArray);
//Testing true or false
System.out.println(first.equals(secondArray));
//Initializing more arrays
String[][] thirdArray = {
{"Hello", "Goodbye"},
{"Hola", "Adios"},
{"Bonjour", "Au revoir"}};
String[][] fourthArray = {
{"Hello", "Goodbye"},
{"Ciao", "Addio"},
{"Bonjour", "Au revoir"}};
//Creating TwoDArray object for comparisons
TwoDArray third = new TwoDArray(thirdArray);
//Testing true or false
System.out.println(third.equals(fourthArray));
}
}
Since you require every corresponding element in the arrays to be equal, then you should simply quit the loops when finding something unequal. For example you can return false; in that case, while returning true only if the loops finish (which would mean all corresponding elements are equal).
With your current code, only the last element is taken into account (which will overwrite the isEqual with whatever result is the equality of the last two elements), while all previous values will not be taken into account.
Also, if you allow myArray to contain null elements, then consider using Objects.equals method to compare the objects for equality, but that's just a hint and not really related to the immediate problem.
As pointed out by #Jems, is should also be noted that in the following lines:
if (myArray.length != other.length)
{
return isEqual;
}
you are testing for equality only the number of rows each 2D array has. Note that you should also probably be comparing each row of each array for equality between their columns. For example something like:
if (myArray[i].length != other[i].length)
return false;
Not to mention the arrays being null themselves should be checked (that is both myArray, myArray[i], other and other[i]).
You can take the code of the Arrays.equals method and customize it so that it accepts 2D arrays:
public static void main(String[] args) {
Integer[][] one = {{1, 2}, {3, 4}, {5, 6}, null};
Integer[][] two = {{1, 2}, {3, 4}, {5, 6}, null};
String[][] three = {{"A", "B"}, {"C", "D"}, {"E", null}};
String[][] four = {{"A", "B"}, {"C", "D"}, {"E", null}};
System.out.println(equals2D(one, two)); // true
System.out.println(equals2D(three, four)); // true
}
/**
* The two 2D arrays are equal if they contain the same rows
* in the same order. Also, two array references are considered
* equal if both are 'null'.
*/
public static boolean equals2D(Object[][] a1, Object[][] a2) {
if (a1 == a2) return true;
if (a1 == null || a2 == null || a1.length != a2.length)
return false;
for (int i = 0; i < a1.length; i++)
if (!equals1D(a1[i], a2[i]))
return false;
return true;
}
/**
* The two rows are equal if they contain the same elements
* in the same order. Also, two row references are considered
* equal if both are 'null'.
*/
public static boolean equals1D(Object[] a1, Object[] a2) {
if (a1 == a2) return true;
if (a1 == null || a2 == null || a1.length != a2.length)
return false;
for (int i = 0; i < a1.length; i++)
if (!Objects.equals(a1[i], a2[i]))
return false;
return true;
}
I'm having trouble with the code in my else statement. I can't figure out how to make it recursively return the 2 adjusted items in the list. I would appreciate any help.
public static int[] fibaux(int n) {
if (n == 1) {
return new int[] {1, 0};
}
else {
int[] array = new int[2];
list[] = {fibaux(n - 1)};
return //array[0] + array[1], array[1];
}
}
Multi-value returns are not allowed in Java i.e., you can not return 2 values using the return. You can simply return an array containing the two values like this:
return new int[] {num1, num2};
I think what you're looking for doesn't involve doing the recursion as part of the return. You want to do the recursion, and then return an array that is the addition of the two elements, along with the one element you want to keep.
I think you want:
public static int[] fibaux(int n) {
if (n == 1) {
return new int[] {1, 0};
}
else {
int[] array = fibaux(n - 1);
return new int[] {array[0]+array[1], array[0]};
}
}
I have a class in java which contains two integers and an array of integers as members and I want to make a hash map with the above object as key. How should i override the equals operator and hashCode() such that the object which have same Integer values as that of members and same entries in the array get the same Hash Code?(or is such a thing even possible) Thanks in Advance.
Use java.util.Arrays#equals(int[], int[]) and Arrays.hashCode(int[])
To calculate a hashcode for the int array you can use java.util.Arrays.hashcode(int[]).
If you look at its implementation:
public static int hashCode(int a[]) {
if (a == null)
return 0;
int result = 1;
for (int element : a)
result = 31 * result + element;
return result;
}
you can derive an idea how to calculate a hash code for your class which should be based on the values of your two integers and the integer array:
public class MyClass {
private int a, b;
private int[] array;
public int hashCode() {
return (31 * (31 * Arrays.hashCode(array) + a)) + b;
}
To equals implementation can look like:
public int equals(Object o) {
if (o instanceof of MyClass) {
MyClass m = (MyClass)o;
return m.a == a && m.b == b && Arrays.equals(m.array, array);
}
else
return false;
}
You can check for array equality using the java.util.Arrays class:
int[] array1 = { 1, 2, 3 };
int[] array2 = { 1, 2, 3 };
boolean equal = Arrays.equals(array1, array2) // --> true
To calculate the hash code of an array, the same class can help you out as well:
int hash = Arrays.hashCode(new int[] { 1, 2, 3 })
Note that the class has overloaded methods for all array types - including Object[].
I have an array and I have to write a method with boolean return type to check the elements of array to see if they are in ascending order using recursion. What I want to do is to break out of recursion AND at the same time return false as soon as I find the first violation. Is that possible and if yes how?
The exercise tells that I have to use recursion not for or while loop. This is what I have written so far.
public class ProveIfSorted
{
public static void main(String args[])
{
int[] myArray = new int[] {1, 3, 5, 7, 9};
System.out.println("The array is sorted: " + checkSorted(myArray, 4);
}
private static boolean checkSorted(int[] array, int i)
{
if(i == 0)
{
boolean isSorted = true;
return isSorted;
}
else
{
if(array[i] >= array[i - 1] == isSorted(int[] array, (i - 1))
{
return isSorted = true;
}
else
{
?????;
}
}
}
}
private boolean isSorted(int[] arr, int start) {
if (arr.length - start < 2)
return True;
if (arr[start] > arr[start+1])
return False;
return isSorted(arr, start+1)
}
Seems relatively straightforward. I'll describe pseudocode, since the actual code is simple enough.
(Prerequisite: your function should accept the array and two ints (first, second) as arguments. Another variation is to have one int parameter, and use it in two contexts.)
Boundary check on the array - if it's zero or null, return false.
Boundary check on the two int arguments: if the second argument is larger than the length of the array, return true. We've since stepped off of the array, and found no violations.
Actual check conditions:
If the value in the array[first] is less than (or equal to) the value in array[second], then we can safely continue recursion; return the call of the method and increment first and second by 1.
Otherwise, return false.
This code will recursively check if the element is less than the element above it. The recursive part is that it will return the call to itself. If the element is less than the next, it continues. If it hits the end, it returns true. If at any time the element is greater than the next, it will return false, stopping the recursion.
public static void main(String args[]){
int[] myArray = new int[] {1, 3, 5, 3, 6};
int[] myArray1 = new int[] {1, 3, 5, 6, 6};
System.out.println("The array is sorted: " + checkSorted(myArray, 0));// Outputs false
System.out.println("The array is sorted: " + checkSorted(myArray1, 0));//Outputs true
}
private static boolean checkSorted(int[] array, int i){
if(i+1 < array.length){
if(array[i] <= array[i+1]){
return checkSorted(array, i+1);
}else{
return false;
}
}
return true;
}
}
Here's an example using tail recursion. Comments should explain. It's deceptively simple.
public class ProveIfSorted{
public static void main( String[] args ){
int[] myArray = new int[]{ 1, 3, 5, 5, 10, 17, 19 };
System.out.println( "The array is sorted: " + checkSorted( myArray ) );
}
/**
* This is the public entry point which should be kept as simple as possible.
* All the caller has is the array, so that is all that should be asked.
* The public interface should not pass the burden of setup to the caller.
* Think of this as the wrapper or setup method for the recursive method.
*
* #param array the array under test. Null or empty arrays are considered to
* be unsorted -- by definition.
* #return {#code true} if the array is sorted ascending.
*/
public static boolean checkSorted( int[] array ){
// Now we call the recursive method -- if the array is not null. Here we
// pass in index values and an indicator for what we have found so far.
// At this point, all we're conserned about is if the array is null or
// empty.
return checkSorted( array, 1, array != null && array.length > 0 );
}
/**
* This is the private work horse. Using tail recursion, we can exit if the
* result of the previous invocation found the array to be unsorted or if we
* have arrived at the end of the array. Otherwise, we call ourselves with
* the next index value and the result of the comparison of this entry with
* the previous entry.
*
* #param array the array under test
* #param ndx the array slot to examine with the previous slot
* #param sorted the result of the last examination. As long as this is
* {#code true}, we continue testing.
* #return {#code true} if the array is sorted ascending.
*/
private static boolean checkSorted( int[] array, int ndx, boolean sorted ){
if( !sorted || ndx == array.length ){
return sorted;
}
else{
return checkSorted( array, ndx + 1, array[ ndx - 1] <= array[ ndx] );
}
}
}
If the function does just that then simply write return false within the loop when you find your match and at the end outside your loop write return true. If function has additional activities to perform aftr this check, then create a boolean variable with default value true before your loop, set the boolean variable to false within loop when it matches and add a break statement.
E.g.
boolean Nomatch = true;
for(int i=0;i<10;i++) {
if(i==5) {
Nomatch = false;
break;
}
}
The following Java code:
public static void main(String args[]) {
int[] x = new int[] {1, 2, 3};
int[] y = new int[] {1, 2, 3};
LinkedList<int[]> list = new LinkedList<int[]>();
list.add(x);
System.out.println("List contains y: " + list.contains(y));
}
gives the output
List contains y: false
which makes sense as x and y are references to different memory locations, however there is also a sense in which they are equal (they have the the same elements in the same order).
Is there a data structure which would return true to the query list.contains(y) in this example?
I don't believe there is a Java data structure that would return true for contains() as you have described.
The issue, as you probably know, is that for Java arrays, equals() only tests for Object identity and not "equality" as most would define it.
Since contains() relies on equals() in this case (and most of the time), you're stuck with the given behaviour.
You would have to implement a List that specifically overrode contains() to provide your desired behaviour for Java arrays, probably using Arrays.equals().
My suggestion is to instead use a List instead of an array; you'd then have a List<List<Integer>>. contains() should work in this scenario as it'll use equals() on the underyling List implementation.
You need to define a comparator for your arrays. Then when the list looks up the elements, it will use your comparator to see if they're the same:
public static void main(String args[]) {
int[] x = new int[] {1, 2, 3};
int[] y = new int[] {1, 2, 3};
LinkedList<int[]> list = new LinkedList<int[]>(new Comparator<int[]>() {
#Override
public int compare(int[] a1, int[] a2) {
if(a1 == a2) return 0;
if(a1 == null && a2 != null) return -1;
if(a1 != null && a2 == null) return 1;
if(a1.size() < a2.size()) return -1;
if(a1.size() > a2.size()) return 1;
for(int i = 0; i < a1.size(); i++) {
int comp = a1[i] - a2[i];
if(comp < 0) return -1;
if(comp > 0) return 1;
}
return 0;
}
});
list.add(x);
System.out.println("List contains y: " + list.contains(y));
}
It looks like you're really looking for a Set implementation.
A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied
by its name, this interface models the mathematical set abstraction.
If you want to store sets of int values, you can use this Tuple class I wrote a while ago for another question on SO.
Set<Tuple> myTuples = new HashSet<Tuple>();
Tuple<Integer> x = Tuple.create(1, 2, 3);
Tuple<Integer> y = Tuple.create(1, 2, 3);
myTuples.add(x);
System.out.println("Set contains y: " + myTuples.contains(y)); // prints true
If order matters, you can use a SortedSet.
LinkedList uses equals to implement contains, so this should work:
public static void main(String args[]) {
static class Ints {
int[] array;
public Ints(int[] array) {
this.array = array;
}
public boolean equals(Object other) {
if (other instanceof Ints) {
return arraysEqual((Ints) other);
}
}
public boolean arraysEqual(Ints other) {
// check that this.array and other.array are same length and
// have same values. Do a null check somewhere too. :)
}
}
Ints x = new Ints(new int[] {1, 2, 3});
Ints y = new Ints(new int[] {1, 2, 3});
LinkedList<Ints> list = new LinkedList<int[]>();
list.add(x);
System.out.println("List contains y: " + list.contains(y));
}
You would probably want to extend LinkedList into your own custom data structure and define a custom equality method if you wanted anything outside of the standard checking that is in place.
If you could use a Set instead of an array it might be easier. Have a look here or here