I need to write a program which defines two arrays of int's and prints all elements of the first array which do not appear in the second, but each value once only, without repetitions (the order of printed values is irrelevant).
For example for arrays:
int[] arr = { 4, 3, 4, 3, 6, 7, 4, 8, 2, 9 };
int[] brr = { 2, 3, 6, 8, 1, 5 };
The result should be:
7 4 9
It only use the java.lang. package and it can't create any arrays, collections or Strings.
This prints all elements of the first array which do not appear in the second, now you just have to check for repetitions.
public static void compareArrays(int[] arr1, int[] arr2) {
boolean equal = false;
int[] printed = null;
for (int i = 0; i < arr1.length; i++) {
for (int x = 0; x < arr2.length; x++) {
if (arr1[i] == arr2[x]) {
equal = true;
break;
} else {
equal = false;
}
}
if (equal != true) {
System.out.println(arr1[i]);
}
}
}
public static void main(String[] args) {
int[] arr = { 4, 3, 4, 3, 6, 7, 4, 8, 2, 9 };
int[] brr = { 2, 3, 6, 8, 1, 5 };
compareArrays(arr, brr);
}
I will give you some pointers, but will not provide any code as I've not seen any attempt from your side. You can tackle this problem several ways, have a look and try to implement this yourself. You will learn much more during the process, rather than if someone gives you a complete full-code answer. So here goes:
First method:
Create a new ArrayList that will hold your output.
Iterate through the first array, iterate through the second array. Compare each value.
If value is not present and is not present in the output list (you would need to check for that specifically, so you dont have repetition of values), then add it to output list.
Print output list.
Second method:
Convert both arrays into an ArrayList.
Use the removeAll() method provided with Lists to get difference between the arrays. This will be stored in one of the lists you created earlier.
Remove repetitive items from the list (e.g. using Streams).
Third method:
Create a new ArrayList that will hold your output.
Iterate through values of array1.
Initialize a boolean variable (e.g. call it contains) that will determine whether a value from array1 is present in array2 using an IntStream.
Create if statement - if contains is true, add the value to your output list. Check that your output List already doesn't have the value and only add if it doesn't. Print output list.
Try using this instead:
String[] unique = new HashSet<String>(Arrays.asList(arr)).toArray(new String[0]);
for (int uEach : unique) {
for (int bEach : brr) {
if (unique[uEach] == brr[bEach]) {
ArrayUtils.removeElement(unique, uEach);
}
}
};
System.out.print(unique);
You can use to get distanct value from an array:
int[] unique = Arrays.stream(arr).distinct().toArray();
Then loop over both arrays and match strings if not found print that:
int i, j, occ;
int[] arr = { 4, 3, 4, 3, 6, 7, 4, 8, 2, 9 };
int[] brr = { 2, 3, 6, 8, 1, 5 };
arr = Arrays.stream(arr).distinct().toArray();
for (i = 0; i < arr.length; i++) {
occ = 0;
for (j = 0; j < brr.length; j++) {
if (arr[i] == brr[j]) {
occ++;
}
}
if (occ == 0) {
System.out.println(arr[i]);
}
}
static void findMissing(int a[], int b[]) {
for (int i = 0; i < a.length; i++) {
int j;
for (j = 0; j < b.length; j++) {
if (a[i] == b[j]) {
break;
}
}
if (j == b.length) {
System.out.print(a[i] + " ");
}
}
}
Related
I need to remove 3 consecutive integers, done with the code but i am not able to print the last index number. can you please help me out..
here is the code..
public class MyClass {
public static void main(String args[]) {
int[] list={ 1, 1, 1, 2, 3, 4, 5, 5, 6, 5, 7, 8, 9};
for(int i=0; i<list.length;i++)
{
if((list[i]==list[i+1]) )
{
if(list[i]==list[i+2])
{
i=i+2;
continue;
}
System.out.print(list[i]) ;
}
else
{
System.out.print(list[i]);
}
}
}
}
As stated by #Dr.Will in his/her answer, one of the problems in your code is the check i < list.length.
Anyway, it's not the only one: you are accessing [i+1] and [i+2] elements without checking if those two values are acceptable indexes.
I just want to add some hint:
Use a debugger while writing such algorithms (it may save you A LOT of time)
cache the value of intermediate results, to avoid multiple access to the same element of the array
cache the size of the array, for the same reason, or use a reverse loop (which has some advantages)
The result would look something like this:
public class MyClass {
public static void main(String... args) {
int[] list = { 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 5, 7, 8, 9}; // sample list
int len = list.length;
if(len < 3)
return; // avoid ArrayIndexOutOfBoundsException
// forward loop
System.out.println("Forward loop:");
int elem1;
for(int i = 0; i < len; i++){
elem1 = list[i];
if(i+1 < len && elem1 != list[i+1])
System.out.println(elem1);
else if (i+2 < len && elem1 == list[i+2] && ++i < len){
// note that "&&" in java is a shot-circuit "AND", so the last "++i" will not be executed if not necessary
// also note that i'm not incrementing "+2", because the for loop will add another "+1" just after this "continue" statement
continue;
} else
System.out.println(elem1);
}
// reverse loop
System.out.println("\nReverse loop (if the order is not that relevant):");
for(int i = len; --i >= 0;){
elem1 = list[i];
if(i-1 >= 0 && elem1 != list[i-1])
System.out.println(elem1);
else if(i-2 >= 0 && elem1 == list[i-2] && --i >= 0)
continue;
else
System.out.println(elem1);
}
}
}
thank you for your logic (–Marco Carlo Moriggi), your logic is helpful and also slightly look complicated, but i changed or edited one line after referring your logic, this seems not much complicated as your logic but gives same result.
public class MyClass {
public static void main(String args[]) {
int[] list={ 1, 1, 1, 2, 3, 4, 5, 5, 6, 5, 7, 8, 9};
int elem = list.length;
for(int i=0; i<list.length;i++)
{
if((i+2<elem) && (list[i]==list[i+1]) )
{
System.out.print(list[i] + " ") ;
if(list[i]==list[i+2])
{
i=i+2;
continue;
}
}
else
{
System.out.print(list[i] + " ");
}
}
}
}
I think that is the i<list.length-1 clause. Your lis.length will return a value of 13, if i remember how to count, adding the -1, you are giving a value of 12, and if you add the <, you´re telling the i to only reach the 11 position.
So i think the solution could be either one of these:
for(int i=0; i<=list.length-1;i++)
or
for(int i=0; i<list.length;i++)
For some reason, my solution is not complete. I got 80/100 from hidden spec tests.
What's wrong with my solution? There is probably a certain use case that I'm not thinking of.
How would space/time complexity change using an ArrayList instead of an array?
Is there a better way to tackle this problem?
My current solution handles:
an empty input array
negative/positive integer values in the input array
duplicates in the input array
sorted/unsorted input array
Instructions:
Write a Java method removeLastOccurrence(int x, int[] arr), which removes the last occurrence of a given integer element x from a given array of integer elements arr.
The method should return a new array containing all elements in the given array arr except for the last occurrence of element x. The remaining elements should appear in the same order in the input and the returned arrays.
The code on the right shows you a code framework in which the implementation of one static method is still missing. Provide this implementation and check that it is correct by either writing more tests yourself or using the provided tests and specification tests.
My code:
class RemoveLastOccurrenceArray {
/**
* Takes the array and the last occurring element x,
* shifting the rest of the elements left. I.e.
* [1, 4, 7, 9], with x=7 would result in:
* [1, 4, 9].
*
* #param x the entry to remove from the array
* #param arr to remove an entry from
* #return the updated array, without the last occurrence of x
*/
public static int[] removeLastOccurrence(int x, int[] arr) {
// if arr == null return null;
if (arr == null || arr.length == 0) return arr;
// return a new array which will be size arr.legnth-1
int[] res = new int[arr.length - 1];
// introduce an int tracker which keep tracks of the index of the last occurrence of x
int last_index = -1;
// traverse through the array to get the index of the last occurrence
for (int i = 0; i < arr.length; i++) if (arr[i] == x) last_index = i;
int i = 0, j = 0;
// copying elements of array from the old one to the new one except last_index
while (i < arr.length) {
if (i == last_index) {
if (i++ < res.length) {
res[j++] = arr[i++];
}
} else res[j++] = arr[i++];
}
// if we pass in x which is not in the array just return the original array
if (last_index == -1) return arr;
// are there duplicates in the array? - WORKS
// does the array have negative numbers? - WORKS
// Is the array sorted/unsorted - WORKS
return res;
}
}
Passing Unit Tests
import static org.junit.Assert.*;
import org.junit.*;
public class RemoveLastOccurrenceArrayTest {
#Test
public void testRemoveArray_Empty() {
int[] array = new int[0];
assertEquals(0, RemoveLastOccurrenceArray.removeLastOccurrence(5, array).length);
}
#Test
public void testFirstSimple() {
int[] input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] result = {2, 3, 4, 5, 6, 7, 8, 9, 10};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(1, input));
}
#Test
public void testLastSimple() {
int[] input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] result = {1, 2, 3, 4, 5, 6, 7, 8, 9};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(10, input));
}
#Test
public void testPositiveInMiddleDuplicate() {
int[] input = {1, 2, 3, 3, 4, 5};
int[] result = {1, 2, 3, 4, 5};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(3, input));
}
#Test
public void testNegativeFirst() {
int[] input = {-3, -1, 2, -3, 3, 4, 5, 0};
int[] result = {-3, -1, 2, 3, 4, 5, 0};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(-3, input));
}
#Test
public void testLasttoRemove() {
int[] input = {1, 4, 7, 9};
int[] result = {1, 4, 7};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(9, input));
}
}
Why not try iterating backwards?
for(int i = arr.length; i => 0; i--)
{
if (arr[i] == x)
{
return ArrayUtils.remove(arr, i)
}
}
Then, after you find the index, you can use the Apache Commons ArrayUtils remove command to remove the item at the
This is the answer thank you very much!
Also, if there is no x to find, yours crashes ... mine doesn't. Maybe that's where the twenty marks went?
I was already checking for this but too late in my code. So I just had to move
if (last_index == -1) return arr; before the while loop, and I got 100/100 scores.
Would your prof prefer this? Just another way, and I don't think any more efficient than your answer. But maybe they like to see the java classes used ...
Does your prof not tell you where you lost marks? You can't improve if they don't tell you what they were expecting for full marks. But here was another way ... again, no better in my opinion, and not worth twenty more marks. I'll just post it, because it is 'another way.'
public int[] removeLastOccurrence2(int x, int[] arr) {
// if arr == null return null;
if (arr == null || arr.length == 0) return arr;
// Fill an ArrayList with your initial array ...
java.util.List list = new java.util.ArrayList(arr.length);
for (int i=0; i<arr.length; i++) {
list.add(arr[i]);
}
int[] res;
// Now ... use ArrayList methods to do the work.
// Also, if there is no x to find, yours crashes ... mine doesn't.
// Maybe that's where the twenty marks went?
if ( list.lastIndexOf(x) != -1 ) { // This screens for no x found at all ...
list.remove( list.lastIndexOf(x) ); // Done!
// Make a new array to return.
res = new int[list.size()];
for (int i=0; i<list.size(); i++) {
res[i] = (int) list.get(i);
}
} else {
// No 'x' found, so just return the original array.
res = arr;
}
return res;
}
How about reverse(), remove(), reverse()? Sorry if this is already mentioned in here somewhere and I missed it.
I am trying to sort an array to a specific order. So for example, I have this array
{6,1,1,5,6,1,5,4,6}
and I want them to be sorted to this order
{4,1,6,5}
expected new array would be
{4,1,1,1,6,6,6,6,5}
My idea is this,
public class Sort {
static int[] list = { 6, 1, 1, 5, 6, 1, 6, 4, 6 };
static int[] sorted = { 4, 1, 6, 5 };
static int[] newList = new int[list.length];
static int count = 0;
public static void main(String[] args) {
for (int i = 0; i < sorted.length; i++) {
for (int j = 0; j < list.length; j++) {
if (list[j] != sorted[i])
continue;
else
newList[count++] = sorted[i];
}
}
}
}
It works fine, however, I am not sure if this is the fastest and easier way to do this regarding speed and memory cause the list could have too many numbers.
You can use java built-in sort algorithm with a customized comparator.
public static void main(String[] args) {
Integer[] list = { 6, 1, 1, 5, 6, 1, 6, 4, 6 };
int[] sorted = { 4, 1, 6, 5 };
Map<Integer, Integer> order = new HashMap<>();
for (int i = 0; i < sorted.length; i++)
order.put(sorted[i], i);
Arrays.sort(list, (a ,b) -> order.get(a) - order.get(b));
System.out.println(Arrays.toString(list));
}
The output is [4, 1, 1, 1, 6, 6, 6, 6, 5].
If you
know the possible elements in advance
and they are relatively small numbers
you can simply count them:
int stats[]=new int[7]; // "largest possible element"+1
for(int i=0;i<list.length;i++)
stats[list[i]]++;
and then reconstruct the ordered list:
int idx=0;
for(int i=0;i<sorted.length;i++){
int val=sorted[i];
for(int j=stats[val];j>0;j--)
newlist[idx++]=val;
The two snippets in total have "2*list.length" steps, which is probably faster than your original "sorted.length*list.length" loop-pair.
As you have not described the actual use-case, it is hard to tell more. For example if you have these numbers only, you probably do not need the ordered result to be an actual list. However if these numbers are just part of an object, this build-a-statistics approach is not applicable.
Hi, I'm a newbie to Java and I was doing this lab assignment where we compare elements of two arrays to get the common elements. I am stuck on how to get rid of duplicates.
My current code is giving me the output [3, 0, 5, 6, 5, 0, 9, 0] and the desired output of common is [3, 5, 6, 9, 0, 0, 0, 0].
Also, since I am not that experienced, please do not post professional ways to do the problem or "experienced" answers to my question, as that would not help me at all :D.
Thanks!
public static void main (String[] args) {
int[] a1 = {3, 8, 5, 6, 5, 8, 9, 2};
int[] a2 = {5, 15, 4, 6, 7, 3, 9, 11, 9, 3, 12, 13, 14, 9, 5, 3, 13};
int[] common = new int[a1.length];
System.out.println("Exercise 3: ");
findCommon(a1,a2,common);
}
public static void findCommon(int[] a1, int[]a2, int[] common) {
int num = 0;
for (int i = 0; i < common.length; i++)
{
for (int j = 0; j < a2.length; j++)
{
if (a1[i] == a2[j]) // loops through every index of j, while keeping i at one index
num = a1[i];
for (int k = 0; k < common.length; k++) // makes sure there are no duplicates in common
{
if (num != common[k])
common[i] = num;
}
}
}
for (int elements : common)
System.out.print(elements + " ");
}
You should look into using Sets to do this kind of thing, but since this is an exercise I've provided a solution with some comments along the way in the code.
Basically you should break the problem down into pieces, each of which is its own method. That way you will have an easier time getting it straight.
arrayIntersect(int[], int[])
This method's job is to create an array from two arrays. The resulting array must have unique elements that are present in both arrays.
You can do n. 1 with a helper method (mentioned below).
inArray(int, int[])
This method returns true if an array contains the given element, false otherwise.
Example
public static void main (String[] args) {
int[] a1 = {3, 8, 5, 6, 5, 8, 9, 2};
int[] a2 = {5, 15, 4, 6, 7, 3, 9, 11, 9, 3, 12, 13, 14, 9, 5, 3, 13};
int[] a3 = arrayIntersect(a1, a2);
for (int a : a3) {
System.out.println(a);
}
}
private static int[] arrayIntersect(int[] a1, int[] a2) {
int[] intersect = new int[Math.min(a1.length, a2.length)];
int curIndex = 0;
for (int x : a1) {
if (inArray(x, a2) && !inArray(x, intersect)) {
intersect[curIndex] = x;
curIndex++;
}
}
// resize intersect array to not include unused indexes
int[] tmp = intersect;
intersect = new int[curIndex];
for (int i = 0; i < intersect.length; i++) {
intersect[i] = tmp[i];
}
return intersect;
}
private static boolean inArray(int element, int[] array) {
boolean result = false;
for (int a : array) {
if (element == a) {
result = true;
break;
}
}
return result;
}
You are very close to the correct anwser, but the for loop for (int k = 0; k < common.length; k++) is being executed for every element of a2. So, when an value exist for a1 but doesn't exist for a2, you are putting the old value of num at the common array. If you look at the elements printed, you will see that every time that an element just exist in a1, the element repeat.
The result of the code is
3 3 5 6 5 5 9 9
You put the right identation, but forgot the curly brackets. If you put the curly brackets at the if (a1[i] == a2[j]), this will be the result:
3 0 5 6 5 0 9 0
But why these 0 are there? Because when you create an int array in java, all elements start with the value of 0. And you are putting the common elements at the same position of the presence of this elements in the a1 array. You can correct this by populating the int array with an invalid number and them ignorin it. At this code, I assumed that -1 is an invalid value.
public static void findCommon(int[] a1, int[] a2, int[] common) {
int num = 0;
for (int i = 0; i < common.length; i++) {
common[i] = -1;
}
for (int i = 0; i < common.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) { // loops through every index of j, while keeping i at one index
num = a1[i];
for (int k = 0; k < common.length; k++) // makes sure there are
// no duplicates in common
{
if (num != common[k])
common[i] = num;
}
}
}
}
for (int elements : common) {
if (elements != -1)
System.out.print(elements + " ");
}
}
If you see, At the if (elements != -1) I didn't put the curly brackets but it worked. If you don't put the curly brackets, it will just execute the next command.
Here is the program task:
Write a method called collapse that accepts an array of integers as a parameter and returns a new array containing the result of replacing each pair of integers with the sum of that pair.
For example, if an array called list stores the values
{7, 2, 8, 9, 4, 13, 7, 1, 9, 10}
then the call of collapse(list) should return a new array containing:
{9, 17, 17, 8, 19}.
The first pair from the original list is collapsed into 9 (7 + 2), the second pair is collapsed into 17 (8 + 9), and so on. If the list stores an odd number of elements, the final element is not collapsed.
For example, if the list had been {1, 2, 3, 4, 5}, then the call would return {3, 7, 5}. Your method should not change the array that is passed as a parameter.
Here is my currently-written program:
public static int[] collapse(int[] a1) {
int newArrayLength = a1.length / 2;
int[] collapsed = new int[newArrayLength];
int firstTwoSums = 0;
for (int i = 0; i < a1.length-1; i++) {
firstTwoSums = a1[i] + a1[i+1];
collapsed[collapsed.length-1] = firstTwoSums;
}
return collapsed;
}
I pass in an array of {7, 2, 8, 9, 4, 13, 7, 1, 9, 10} and I want to replace this array with {9, 17, 17, 8, 19}.
Note:{9, 17, 17, 8, 19} will be obtained through the for-loop that I have written.
Currently, I am having trouble with adding the integers I obtained to my "collapsed" array. It'd be a great help if you could help me or at least give me some guidance on how to do this.
Thanks in advance!
First you have to understand what is going on.
You have an array of certain size where size can either be even or odd. This is important because you are using a1.length/2 to set the size for new array, so you will also have to check for odd and even values to set the size right else it won't work for odd sized arrays. Try a few cases for better understanding.
Here's a way of doing it.
public static int[] collapseThis(int[] array) {
int size = 0;
if(isEven(array.length))
size = array.length/2;
else
size = array.length/2+1;
int[] collapsedArray = new int[size];
for(int i=0, j=0; j<=size-1; i++, j++) {
if(j==size-1 && !isEven(array.length)) {
collapsedArray[j] = array[2*i];
}
else {
collapsedArray[j] = array[2*i]+array[2*i+1];
}
}
return collapsedArray;
}
private static boolean isEven(int num) {
return (num % 2 == 0);
}
Using
collapsed[collapsed.length-1] = firstTwoSums;
The sum of your numbers will be always be put in the same index of the collapsed array, because collapsed.length - 1 is a constant value.
Try creating a new variable starting at zero, that can be incremented each time you add a sum to collapsed. For instance,
int j = 0;
for(...) {
...
collapsed[j++] = firstTwoSums;
}
I think this is a convenient answer.
public static void main(String[] args){
int[] numbers = {1,2,3,4,5};
int[] newList = collapse(numbers);
System.out.println(Arrays.toString(newList));
}
public static int[] collapse(int[] data){
int[] newList = new int[(data.length + 1)/2];
int count = 0;
for (int i = 0; i < (data.length / 2); i++){
newList[i] = data[count] + data[count + 1];
System.out.println(newList[i]);
count = count + 2;
}
if (data.length % 2 == 1){
newList[(data.length / 2)] = data[data.length - 1];
}
return newList;
}
i would combine the cases for the array with either odd or even elements together as below:
public static int[] collapse(int[] a1) {
int[] res = new int[a1.length/2 + a1.length % 2];
for (int i = 0; i < a1.length; i++)
res[i/2] += a1[i];
return res;
}
public static int[] collapse(int[] a1) {
int newArrayLength = a1.length / 2;
int[] collapsed;
if(a1.length%2 == 0)
{
collapsed = new int[newArrayLength];
}
else
{
collapsed = new int[newArrayLength+1];
collapsed[newArrayLength] = a1[a1.length-1];
}
int firstTwoSums = 0;
for (int i = 0; i < newArrayLength; i++) {
firstTwoSums = a1[i*2] + a1[i*2+1];
collapsed[i] = firstTwoSums;
}
return collapsed;
}
I modified your code and you may try it first.