I need help because I can not see where my problem is. I have function swapping and it looks like this:
public static void swapping(int[] curr, Integer i, Integer j, Integer k, Integer l, int z, int dist) {
int tmp;
int[] tmpCurr = curr;
if (i >= 0 && j >= 0 && k < 0 && l < 0) {
tmp = tmpCurr[i];
tmpCurr[i] = tmpCurr[z];
tmpCurr[z] = tmp;
nodesHM.put(1, tmpCurr);
for(int s = 0; s<tmpCurr.length; s++)
System.out.println(tmpCurr[s]);
tmpCurr = curr;
tmp = tmpCurr[j];
tmpCurr[j] = tmpCurr[z];
tmpCurr[z] = tmp;
nodesHM.put(2, tmpCurr);
for(int s = 0; s<tmpCurr.length; s++)
System.out.println(tmpCurr[s]);
}
}
i,j,k,l tell me what to swap with z. So if i put that somethig is -1 that means I do not want to swap it. Like it this case k and l.
And I call it from main, like this:
public static void main(String[] args) {
swapping(ourStartState, 3, 7, -1, -1, 6, 5);
}
private static final int[] ourStartState = { 1, 2, 3, 4, 5, 6, 0, 7, 8 };
And it should write me something like: 1,2,3,0,5,6,4,7,8 and 1,2,3,4,5,6,7,0,8
but it give me 1,2,3,0,5,6,4,7,8 and 1,2,3,0,5,6,7,4,8
Where I am going wrong?
Thanks
whenever you copy an array or an object, you just create another reference to the elements in the array.
so when you did tmpcurr=curr you created another reference to curr array, whatever changes you make in curr affects tmpcurr and vice-versa.
if you swap elements in tmpcurr array the elements of curr get swapped as well.
when you swapped elements again you are swapping from already swapped array.
this will help you How do I copy an object in Java?
Related
The title may be a bit confusing so here's an instance. I have two arrays:
int [] scores;
scores = new int[5]; //(5,7,10,3,6)
int [] places;
places = new int[5]; //(1,2,3,4,5)
I need to somehow sort the second array (I can't change the first one), so it represents the highness of elements in the first array. 10 is the highest so its place has to be 1st, 3 is the lowest so its place has to be 5th.
After the sorting second array should look like this:
places = {4,2,1,5,3};
Here's my code, and I need some help to make it work the way it should.
do {
for (int i = 0; i < 5; i++) {
for (int j = 1; j < 5; j++) {
if (scores[i] < scores[j]) {
temp = places[i];
places[i] = places[j];
places[j] = temp;
flag = true;
} else {
flag = false;
}
}
}
} while (flag);
Thanks in advance
#Korashen adviced a pretty good solution,
Another way:
assume all the values of scores are different and positive, you can make a copy of the array,sort it, and by subtaction to know the indexes,
in your example:
before sorting :
scores = (5,7,10,3,6)
after sorting :
scores_sorted = (3,5,6,7,10)
the value of places will be by the following rule:
if(scores_sorted[i]-scores[j] == 0)
places[i] = j
full example:
int[] scores = new int[]{5, 7, 10, 3, 6};
int[] scores_sorted = scores.clone();
int[] places = new int[]{0,1,2,3,4};
sort(scores_sorted);
for(int i=0;i<5;++i){
for(int j=0;j<5;++j){
if(scores_sorted[i]-scores[j] == 0){
places[i] = j;
}
}
}
You can use any sorting algorithm over the places but, instead comparing the places, compare the scores indexed by places.
Here is the modified quickSort:
static int partition(int[] iarray, int[] varray, int begin, int end) {
int pivot = end;
int counter = begin;
for (int i = begin; i < end; i++) {
if (varray[iarray[i]] < varray[iarray[pivot]]) {
int temp = iarray[counter];
iarray[counter] = iarray[i];
iarray[i] = temp;
counter++;
}
}
int temp = iarray[pivot];
iarray[pivot] = iarray[counter];
iarray[counter] = temp;
return counter;
}
public static void quickSort(int[] iarray, int[] varray, int begin, int end) {
if (end <= begin) return;
int pivot = partition(iarray, varray, begin, end);
quickSort(iarray, varray, begin, pivot - 1);
quickSort(iarray, varray, pivot + 1, end);
}
The only change is add the varray argument and the comparison iarray[i] < iarray[pivot] to varray[iarray[i]] < varray[iarray[pivot]].
NOTE: places must be numbers from 0 to n - 1.
If places are keys instead indexes, you need an intermediate Map to convert the varray[iarray[i]] to varray[real_index_of.get(iarray[i])].
A running example could be:
int[] scores = new int[]{5, 7, 10, 3, 6};
int[] places = new int[]{0, 1, 2, 3, 4};
quickSort(places, scores, 0, places.length - 1);
System.out.println(Arrays.stream(scores).mapToObj(Integer::toString).collect(joining(", ")));
System.out.println(Arrays.stream(places).mapToObj(Integer::toString).collect(joining(", ")));
With output:
5, 7, 10, 3, 6
3, 0, 4, 1, 2
(your output is wrong since 5 is the second lowest value)
I want to remove the duplicates by putting them in a new array but somehow I only get a first instance and a bunch of zeros.
Here is my code:
public class JavaApplication7 {
public static void main(String[] args) {
int[] arr = new int[] {1,1,2,2,2,2,3,4,5,6,7,8};
int[] res = removeD(arr);
for (int i = 0; i < res.length; i++) {
System.out.print(res[i] + " ");
}
}
public static int[] removeD(int[] ar) {
int[] tempa = new int[ar.length];
for (int i = 0; i < ar.length; i++) {
if (ar[i] == ar[i+1]) {
tempa[i] = ar[i];
return tempa;
}
}
return null;
}
}
expected: 1,2
result: 1,0,0,0,0,0,0....
why dont you make use of HashSet?
final int[] arr = new int[] { 1, 1, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8 };
final Set<Integer> set = new HashSet<>();
for (final int i : arr) {
// makes use of Integer's hashCode() and equals()
set.add(Integer.valueOf(i));
}
// primitive int array without zeros
final int[] newIntArray = new int[set.size()];
int counter = 0;
final Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()) {
newIntArray[counter] = iterator.next().intValue();
counter++;
}
for (final int i : newIntArray) {
System.out.println(i);
}
Edit
if you want your array to be ordered
final int[] arr = new int[] { 9, 9, 8, 8, 1, 1, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8 };
Set<Integer> set = new HashSet<>();
for (final int i : arr) {
// makes use of Integer's hashCode() and equals()
set.add(Integer.valueOf(i));
}
// priomitive int array without zeros
final int[] newIntArray = new int[set.size()];
int counter = 0;
// SetUtils.orderedSet(set) requires apache commons collections
set = SetUtils.orderedSet(set);
final Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()) {
newIntArray[counter] = iterator.next().intValue();
counter++;
}
for (final int i : newIntArray) {
System.out.println(i);
}
A couple of points to help you:
1) With this: for(int i =0; i<ar.length; i++){ - you will get an IndexOutOfBoundsException because you are checking [i+1]. Hint: it is only the last element that will cause this...
2) Because you're initialising the second array with the length of the original array, every non-duplicate will be a 0 in it, as each element is initialised with a 0 by default. So perhaps you need to find how many duplicates there are first, before setting the size.
3) As mentioned in the comments, you are returning the array once the first duplicate is found, so remove that and just return the array at the end of the method.
4) You will also get multiple 2s because when you check i with i+1, it will find 3 2s and update tempa with each of them, so you'll need to consider how to not to include duplicates you've already found - based on your expected result.
These points should help you get the result you desire - if I (or someone else) just handed you the answer, you wouldn't learn as much as if you researched it yourself.
Here:
int[] tempa = new int[ar.length];
That creates a new array with the same size as the incoming one. All slots in that array are initialized with 0s!
When you then put some non-0 values into the first slots, sure, those stick, but so do the 0s in all the later slots that you don't "touch".
Thus: you either have to use a data structure where you can dynamically add new elements (like List/ArrayList), or you have to first iterate the input array to determine the exact count of objects you need, to then create an appropriately sized array, to then fill that array.
Return statement
As both commenters said, you return from the method as soon as you find your first duplicate. To resolve that issue, move the return to the end of the method.
Index problems
You will then run into another issue, an ArrayIndexOutOfBoundsException because when you are checking your last item (i = ar.length - 1) which in your example would be 11 you are then comparing if ar[11] == ar[12] but ar has size 12 so index 12 is out of the bounds of the array. You could solve that by changing your exit condition of the for loop to i < ar.length - 1.
Zeros
The zeros in your current output come from the initialization. You initialize your tempa with int[ar.length] this means in the memory it will reserve space for 12 ints which are initialized with zero. You will have the same problem after resolving both issues above. Your output would look like this: 1 0 2 2 2 0 0 0 0 0 0 0. This is because you use the same index for tempa and ar. You could solve that problem in different ways. Using a List, Filtering the array afterwards, etc. It depends what you want to do exactly.
The code below has the two first issues solved:
public class JavaApplication7 {
public static void main(String[] args) {
int[] arr = new int[] { 1, 1, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8 };
int[] res = removeD(arr);
for (int i = 0; i < res.length; i++) {
System.out.print(res[i] + " ");
}
}
public static int[] removeD(int[] ar) {
int[] tempa = new int[ar.length];
for (int i = 0; i < ar.length - 1; i++) {
if (ar[i] == ar[i + 1]) {
tempa[i] = ar[i];
}
}
return tempa;
}
}
There were a some error mentioned already:
return exits the method.
with arr[i+1] the for condition should bei+1 < arr.length`.
the resulting array may be smaller.
So:
public static int[] removeD(int[] ar) {
// Arrays.sort(ar);
int uniqueCount = 0;
for (int i = 0; i < ar.length; ++i) {
if (i == 0 || ar[i] != ar[i - 1]) {
++uniqueCount;
}
}
int[] uniques = new int[uniqueCount];
int uniqueI = 0;
for (int i = 0; i < ar.length; ++i) {
if (i == 0 || ar[i] != ar[i - 1]) {
uniques[uniqueI] = arr[i];
++uniqueI;
}
}
return uniques;
}
I'm really new to Java and there's something wrong with the code. No errors were detected, but the output is odd.
The goal is to move the data in an array to the left. For example:
x = {1,2,3}
the new array should be {2,3,1}.
Now the code below only gives me {0,0,0}. It'd be nice if you point out the mistake and tell me what to do. Thanks a lot beforehand!
public class Project1 {
public static int[] shiftone(int[]n,boolean left) {
n = new int[n.length];
int save,save2;
if(left = true){
save = n[0];
save2 = n[(n.length-1)];
for (int i = 1; i < n.length-1; i++) {
n[i-1]=n[i];
}
n[n.length-1] = save;
n[n.length-2] = save2;
}
else{
save = n[n.length-1];
for (int i=0;i<(n.length-1);i++)
n[(n.length)-i] = n[(n.length-1)-1];
n[0] = save;
}
return n;
}
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int[] x;
int k;
boolean left;
System.out.print("Masukkan jumlah data yang ingin diinput: ");
k = input.nextInt();
System.out.println();
x = new int[k];
for (int i = 0; i < k; i++) {
System.out.print("Input data ke-"+i+": ");
x[i] = input.nextInt();
}
System.out.print("Array: "+Arrays.toString(x));
System.out.println();
System.out.print("Move to left? (true/false): ");
left = input.nextBoolean();
System.out.println();
int[] y;
y = new int[k];
y = shiftone(x,left);
System.out.print("New array: "+Arrays.toString(y));
}
}
As a simple solution for your goal, you can use this
public static int[] shiftone(int[] n, boolean left) {
// you don't need to shift anything if length = 1
if (n.length < 2) {
return n;
}
if (left) {
// save first element
int save = n[0];
for (int i = 1; i < n.length; i++) {
// shift from 1 to n
n[i-1] = n[i];
}
// insert saved element to array
n[n.length - 1] = save;
} else {
// the same
int save = n[n.length - 1];
for (int i = 1; i < n.length; i++)
n[n.length - i] = n[(n.length - 1) - i];
n[0] = save;
}
return n;
}
There is the very fast method to copy the array elements from one place to another. I don't know if this will be helpful to you since it seems to me your question is homework assignment. Nevertheless, I'll put the code with appropriate comments...
public class Answer {
public static void main(String[] args) {
//test case
int[] input = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(input));
//save the first element in the temporary variable
int temp = input[0];
//the fastest way to copy the array elements
//1st parameter is the source array
//2nd parameter is the source position (read: from which element to copy)
//3rd parameter is the destination (in this case the same array)
//4th parameter is the destination position (read: where to store the 1st element)
//5th parameter is the length of elements to copy (read: how many)
System.arraycopy(input, 1, input, 0, input.length - 1);
//finally store the saved element to the end
input[input.length - 1] = temp;
System.out.println(Arrays.toString(input));
}
}
If we don't want to code the moving on our own, we can use the method Collections.rotate . It takes a List and rotates the elements by a given distance. To use it, we need to convert the int array to a List<Integer>. The rotated list is converted back to an int array.
protected static int[] move(int[] input, int distance) {
List<Integer> inputList = Arrays.stream(input).boxed().collect(Collectors.toCollection(ArrayList::new));
Collections.rotate(inputList, distance);
return inputList.stream().mapToInt(Integer::intValue).toArray();
}
Usage:
public static void main(String[] args) throws Exception {
int[] input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
int moveLeftOnce = -1;
int[] moved = move(input, moveLeftOnce); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
}
Please note:
Since Collections.rotate will move the elements in the given list, the list has to be modifiable. This is the case for an ArrayList. Therefore the code uses Collectors.toCollection(ArrayList::new) since there are (JavaDoc)
no guarantees on the type, mutability ... of the List returned
by Collectors.toList.
i have integer a = 4 and array b 7,8,9,4,3,4,4,2,1
i have to write a method that removes int ALL a from array b
desired result 7,8,9,3,2,1
This is what I have so far,
public static int[] removeTwo (int x, int[] array3)
{
int counter = 0;
boolean[] barray = new boolean [array3.length];
for (int k=0; k<array3.length; k++)
{
barray[k] = (x == array3[k]);
counter++;
}
int[] array4 = new int [array3.length - counter];
int num = 0;
for (int j=0; j<array3.length; j++)
{
if(barray[j] == false)
{
array4[num] = array3[j];
num++;
}
}
return array4;
I get this error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Utility.removeTwo(Utility.java:50)
at Utility.main(Utility.java:18)
Java Result: 1
Any help would be much appreciated!
The error stems from this for loop:
for (int k=0; k<array3.length; k++)
{
barray[k] = (x == array3[k]);
counter++;
}
when you create int[] array4 = new int [array3.length - counter]; you are creating an array with size 0. You should only increment the counter if the item is the desired item to remove:
for (int k=0; k<array3.length; k++)
{
boolean b = (x == array3[k]);
barray[k] = b;
if(b) {
counter++;
}
}
To answer your question in the comment, the method should be called and can be checked like this:
public static void main(String[] args) {
int[] array3 = {0,1,3,2,3,0,3,1};
int x = 3;
int[] result = removeTwo(x, array3);
for (int n : result) {
System.out.print(""+ n + " ");
}
}
On this line:
int[] array4 = new int [array3.length - counter];
You create an array with size 0, as counter is equal to array3.length at this point.
This means that you cannot access any index in that array.
You are creating
int[] array4 = new int [array3.length - counter];// 0 length array.
you can't have 0th index there. At least length should 1 to have 0th index.
BTW my suggestion, it is better to use List. Then you can do this easy.
Really an Array is the wrong tool for the job, since quite apart from anything else you will end up with stray values at the end that you cannot remove. Just use an ArrayList and that provides a removeAll() method to do what you need. If you really need arrays you can even do:
List<Integer> list = new ArrayList(Arrays.asList(array))
list.removeAll(4);
array = list.toArray();
(Exact method names/parameters may need tweaking as that is all from memory).
the simplest way is to work with a second array where you put in the correct values
something likte that
public static int[] removeTwo (int x, int[] array3)
{
int counter = 0;
int[] array4 = new int[array3.lenght];
for (int i = 0; i < array3.lenght; i ++) {
if(array3[i] == x){
array4[counter] = array3[i];
}
}
return array4;
}
anoterh way is to remove the x calue from the array3 and shift the values behind forward
The best way to remove element from array is to use List with Iterator. Try,
Integer[] array = {7, 8, 9, 4, 3, 4, 4, 2, 1};
List<Integer> list = new ArrayList(Arrays.asList(array));
for(Iterator<Integer> it=list.iterator();it.hasNext();){
if(it.next()==4){
it.remove();
}
}
Please read the question before marking it as duplicate
I have written following code to remove duplicates from array without using Util classes but now I am stuck
public class RemoveDups{
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
int temp;
for (int i : a) {
for (int j = 0; j < a.length - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
a = removeDups(a);
for (int i : a) {
System.out.println(i);
}
}
private static int[] removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
}
}
return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
and now the output is
1
2
3
4
5
6
45
52
0
0
0
0
0
0
0
0
0
0
Here my problem is
My code is not working in case of 0s
I am not able to understand how sorting an array can reduce time of execution
Is there any way to remove elements from array without using Util classes I know one way to remove convert array into list and then remove but for that also we need Util classes is there any way to implement by myself.
Since the numbers you deal with are limited to a small range you can remove duplicates by a simple "counting sort": mark the numbers you have found in a set-like data structure and then go over the data structure. An array of boolean works just fine, for less memory usage you could create a basic bitset or hash table. If n is the number of elements in the array and m is the size of the range, this algorithm will have O(n+m) complexity.
private static int[] removeDups(int[] a, int maxA) {
boolean[] present = new boolean[maxA+1];
int countUnique = 0;
for (int i : a) {
if (!present[i]) {
countUnique++;
present[i] = true;
}
}
int[] result = new int[countUnique];
int j = 0;
for (int i=0; i<present.length; i++) {
if (present[i]) result[j++] = i;
}
return result;
}
I am not able to understand how sorting an array can reduce time of execution
In a sorted array you can detect duplicates in a single scan, taking O(n) time. Since sorting is faster than checking each pair - O(n log n) compared to O(n²) time complexity - it would be faster to sort the array instead of using the naive algorithm.
As you are making the result array of the same length as array a
so even if you put only unique items in it, rest of the blank items will have the duplicate values in them which is 0 for int array.
Sorting will not help you much, as you code is searching the whole array again and again for the duplicates. You need to change your logic for it.
You can put some negative value like -1 for all the array items first in result array and then you can easily create a new result array say finalResult array from it by removing all the negative values from it, It will also help you to remove all the zeroes.
In java , arrays are of fixed length. Once created, their size can't be changed.
So you created an array of size18.
Then after you applied your logic , some elements got deleted. But array size won't change. So even though there are only 8 elements after the duplicate removal, the rest 10 elements will be auto-filled with 0 to keep the size at 18.
Solution ?
Store the new list in another array whose size is 8 ( or whatever, calculate how big the new array should be)
Keep a new variable to point to the end of the last valid element, in this case the index of 52. Mind you the array will still have the 0 values, you just won't use them.
I am not able to understand how sorting an array can reduce time of execution
What ? You sort an array if you need it to be sorted. Nothing else. Some algorithm may require the array to be sorted or may work better if the array is sorted. Depends on where you are using the array. In your case, the sorting will not help.
As for your final question , you can definitely implement your own duplicate removal by searching if an element exists more than once and then deleting all the duplicates.
My code is not working in case of 0
There were no zeroes to begin with in your array. But because its an int[], after the duplicates are removed the remaining of the indexes are filled with 0. That's why you can see a lot of zeroes in your array. To get rid of those 0s, you need to create another array with a lesser size(size should be equal to the no. of unique numbers you've in your array, excluding 0).
If you can sort your array(I see that its already sorted), then you could either bring all the zeroes to the front or push them to the last. Based on that, you can iterate the array and get the index from where the actual values start in the array. And, then you could use Arrays.copyOfRange(array, from, to) to create a copy of the array only with the required elements.
try this
package naveed.workingfiles;
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 0, 3, 1,0, 3, 6, 2};
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
boolean zeroExist = false;
for (int i : a) {
if(i==0 && !zeroExist){
result[j++] = i;
zeroExist = true;
count++;
}
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
// It works even Array contains 'Zero'
class Lab2 {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45 };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i = 0; i < count; i++) {
System.out.println(result[i]);
}
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}