I'm trying to write a method that takes a sorted array and an integer, creates a new array that is 1 size larger, and inserts the new integer and keeps it sorted.
I've tried a few different implementations and had them to work - but for this specific one, I can't grasp where it's going wrong.
int[] array1 = new int[]{1, 2, 3, 4, 6, 7, 8};
int[] printArray = insert(array1, 5);
are the arrays, and the method is
public static int[] insert(int[] a, int k) {
int[] s = new int[a.length + 1];
for(int i = 0; i < a.length; i++) {
if(k < s[i]) {
s[i] = k;
for(int j = i + 1; j < s.length; j++) {
s[j] = a[i];
i++;
}
return s;
} else {
s[i] = a[i];
}
}
return s;
}
This method prints out 1, 2, 3, 4, 6, 7, 8, 0, instead of 1, 2, 3, 4, 5, 6, 7, 8.
Change
if(k < s[i]) {
to
if(k < a[i]) {
in line 4.
Actually in the following line you are creating an array with all elements zero:
int[] s = new int[a.length + 1];
s[0] to s[7] will be 0.
Your loop counter i runs from 0 to a.length but the point to note is all the elements of array s will be zero. You are comparing k with s[i] which is zero and for that reason the shifting of arrays never happen (if block never executes).
You need to do two things to fix it.
Initialize element zero of s with the value of a[0].
Compare element with previous element to figure out position to insert.
The final code is:
public static int[] insert(int[] a, int k) {
int[] s = new int[a.length + 1];
s[0] = a[0];
for(int i = 1; i < a.length; i++) {
if(k < s[i-1]) {
s[i] = k;
for(int j = i + 1; j < s.length; j++) {
s[j] = a[i];
i++;
}
return s;
} else {
s[i] = a[i];
}
}
return s;
}
Now you will get:
[1, 2, 3, 4, 6, 5, 7, 8]
I would start by using Arrays.copyOf(int[], int) to create a new array that is one larger than the input. Then iterate that array until I reached the index that the new value belongs at. Then use System.arraycopy(Object,int,Object,int,int) to copy the values into the end of the array. That might look something like
public static int[] insert(int[] a, int k) {
int[] s = Arrays.copyOf(a, a.length + 1);
for (int i = 0; i < s.length; i++) {
if (a[i] < k) {
continue;
}
System.arraycopy(a, i, s, i + 1, s.length - i - 1);
s[i] = k;
break;
}
return s;
}
Which I tested with Arrays.toString(int[]) like
public static void main(String s[]) throws IOException {
int[] array1 = new int[] { 1, 2, 3, 4, 6, 7, 8 };
int[] printArray = insert(array1, 5);
System.out.println(Arrays.toString(printArray));
}
And I get the (expected)
[1, 2, 3, 4, 5, 6, 7, 8]
Related
The method I have to create should take as parameter an array of integers and return the integer array with its contents sorted in descending order — largest to smallest.
Note - no libraries should be used in your implementation for this method.
I've attempted to use a regular selection sort and using a swap at the end but syntax errors just occurred:
public static int[] reverseSelectionSort(int[] arrayToBeSorted) {
// implementation of Task 3 goes here
for(int i = 0; i < arrayToBeSorted.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < arrayToBeSorted.length - i; j++){
if(arrayToBeSorted[j] < arrayToBeSorted[minPosition]){
minPosition = j;
}
if(arrayToBeSorted[j] > arrayToBeSorted[maxPosition]){
maxPosition = j;
}
}
swap(arrayToBeSorted,minPosition,maxPosition);
swap(arrayToBeSorted,maxPosition,i);
swap(arrayToBeSorted,minPosition,arrayToBeSorted.length-i-1);
}
return arrayToBeSorted; // change this to return the sorted array
}
public static void main(String[] args) {
int[] array2 = {3, 6, 8, 3, 5, 7, 1};
int[] sorted = reverseSelectionSort(array2);
System.out.print("task: [");
for (int i = 0; i < sorted.length; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(sorted[i]);
}
System.out.println("]");
}
If you call the method on the array [3, 6, 8,
3, 5, 7, 1], then the method should return the array [8, 7, 6, 5, 3, 3, 1].
Once you add the implementation of swap to your code (and put it all inside a class), it produces exactly the output you wanted it to. Maybe you thought swap was a java uitl, which it is for Collections, but an array is not a Collection.
So very little has changed in the below:
public class soSelect{ //embed in class, added
public static int[] reverseSelectionSort(int[] arrayToBeSorted) {
// implementation of Task 3 goes here
for(int i = 0; i < arrayToBeSorted.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < arrayToBeSorted.length - i; j++){
if(arrayToBeSorted[j] < arrayToBeSorted[minPosition]){
minPosition = j;
}
if(arrayToBeSorted[j] > arrayToBeSorted[maxPosition]){
maxPosition = j;
}
}
swap(arrayToBeSorted,minPosition,maxPosition);
swap(arrayToBeSorted,maxPosition,i);
swap(arrayToBeSorted,minPosition,arrayToBeSorted.length-i-1);
}
return arrayToBeSorted; // change this to return the sorted array
}
public static void swap(int[] a, int i, int j){ //had to implement it
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void main(String[] args) {
int[] array2 = {3, 6, 8, 3, 5, 7, 1};
int[] sorted = reverseSelectionSort(array2);
System.out.print("task: [");
for (int i = 0; i < sorted.length; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(sorted[i]);
}
System.out.println("]");
}
}//added outer brace
I ran it in java doodle and it printed:
task: [8, 7, 6, 5, 3, 3, 1]
I did not test beyond that, but this should at least get you unstuck, or, at best, finished. For sure you could compare with the implementation to which the above comment points you.
This post - "Java + Count duplicates from int array without using any Collection or another intermediate Array", was also a sample exercise in my book at school, but what I want to do is get the elements that has duplicates without sorting it.
What I did is I removed the duplicates of arrays first, to get only the unique elements and then I compare it to the original array and count how many times the element has been found. But the problem is it doesn't print the correct elements which has duplicates.
int[] num = {7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1};
the correct output should be: 7, 1, 4
but instead it outputs: 7, 6, 1
This is my codes:
//method for removing duplicates
public static int[] removeDuplicates(int[] n) {
int limit = n.length;
for(int i = 0; i < limit; i++) {
for(int j = i + 1; j < limit; j++) {
if(n[i] == n[j]) {
for(int k = j; k < limit - 1; k++) {
n[k] = n[k + 1];
}
limit--;
j--;
}
}
}
int[] uniqueValues = new int[limit];
for(int i = 0; i < uniqueValues.length; i++) {
uniqueValues[i] = n[i];
}
return uniqueValues;
}
//method for getting elements that has duplicates
public static int[] getDuplicatedElements(int[] n) {
int[] nCopy = n.clone();
int[] u = removeDuplicates(nCopy);
int count = 0;
int limit = u.length;
for(int i = 0; i < u.length; i++) {
for(int j = 0; j < n.length; j++) {
if(u[i] == n[j]) {
count++;
}
}
if(count == 1) {
for(int k = i; k < limit - 1; k++) {
u[k] = u[k + 1];
}
limit--;
}
count = 0;
}
int[] duplicated = new int[limit];
for(int i = 0; i < duplicated.length; i++) {
duplicated[i] = u[i];
}
return duplicated;
}
//main
public static void main(String[] args) {
int[] num = {7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1};
//printing original values
System.out.print(Arrays.toString(num));
System.out.println();
int[] a = getDuplicatedElements(num);
System.out.print("Elements with Duplicates: " + Arrays.toString(a));
}
What's the error in my codes here? Please help thanks...
You have two issues:
public static int[] getDuplicatedElements(int[] n) {
int[] nCopy = n.clone();
int[] u = removeDuplicates(nCopy);
System.out.println ("unique " + Arrays.toString (u));
int count = 0;
int limit = u.length;
for(int i = 0; i < limit; i++) { // you must use limit instead of u.length
// in order for the loop to terminate
for(int j = 0; j < n.length; j++) {
if(u[i] == n[j]) {
count++;
}
}
if(count == 1) {
for(int k = i; k < limit - 1; k++) {
u[k] = u[k + 1];
}
limit--;
i--; // you must decrement i after you find a unique element in u
// otherwise you'll be skipping elements in the u array
}
count = 0;
}
int[] duplicated = new int[limit];
for(int i = 0; i < duplicated.length; i++) {
duplicated[i] = u[i];
}
return duplicated;
}
With those fixes, you'll get the expected output:
Elements with Duplicates: [7, 1, 4]
It's fairly simple when using a stream
int[] num = {7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1};
List<Integer> list = Arrays.stream(num).boxed().collect(Collectors.toList());
list.stream().filter(i -> Collections.frequency(list, i) > 1)
.collect(Collectors.toSet()).forEach(System.out::println);
This question already has answers here:
How to efficiently remove duplicates from an array without using Set
(48 answers)
Closed 7 years ago.
I was asked to write a method that accepts a sorted array, removes any duplicate elements found in the array and then places a 0 at the end of the array for every duplicate element found.
It is also supposed to return the number of unique elements found in the array.
Here is my method:
public static int removeDups(int[] arr) {
int j = 0;
int i = 1;
int numDups = 0;
while(i < arr.length) {
if (arr[i] == arr[j]) {
i++;
numDups++;
}
else {
arr[++j] = arr[i++];
}
}
for (int k = j+1; k < arr.length; k++) {
arr[k] = 0;
}
return (j);
}
It successfully finds all the duplicate numbers in the array and places the correct number of 0s at the end, but it doesn't always return the correct value for the number of unique elements.
For example, for the array:
{ 6 10 19 21 23 26 27 36 38 45 }
the number of unique elements should be 10, but it returns 9.
What am I doing wrong?
As it can be seen, j is used as the index of the last unique element.
In an array, i'th index is actually the i + 1'th element counted from 1.
So, you have to return j + 1 instead of j from your method.
Here is a solution to your problem. It keeps track of two pointers, one which only advances when a value gets written to the array, and the other which touches every element of the array in sequential order. When one or more duplicates are encountered, the second pointer keeps advancing, while the first pointer stays put, waiting to write a non-duplicate value. Finally, the code iterates over the remainder of the array from the first pointer, writing out zeroes until the end.
public static int removeDups(int[] arr) {
if (arr == null) {
return null;
}
if (arr.length == 0 || arr.length == 1) {
return arr;
}
int prevIndex = 0;
for (int i=1; i < arr.length; ++i) {
if (arr[prevIndex] != arr[i]) {
arr[prevIndex+1] = arr[i];
++prevIndex;
}
}
for (int i=prevIndex+1; i < arr.length; ++i) {
arr[i] = 0;
}
return prevIndex+1;
}
int[] arr = {1, 2, 3, 3, 4, 5, 6, 6, 6, 10};
removeDups(arr);
System.out.println(Arrays.toString(arr));
Output:
[1, 2, 3, 4, 5, 6, 10, 0, 0, 0]
This code has been tested using IntelliJ and it appears to be working.
Try this!
static int getUniqueElements(int [] sortedArr){
int duplicateCount = 0;
int [] tempArr = sortedArr;
int j=0;
boolean isNewValue = true;
for(int i=1;i<tempArr.length;i++){
if(sortedArr[j] != tempArr[i]){
isNewValue = true;
sortedArr[++j] = tempArr[i];
}else{
if(isNewValue){
isNewValue = false;
duplicateCount++;
}
}
}
for(j++;j<sortedArr.length;j++){
sortedArr[j] = 0;
duplicateCount++;
}
return (sortedArr.length-duplicateCount);
}
public static void main(String[] args) {
int[] arr = {1, 3, 3, 3, 3, 6, 6, 7, 8, 8};
System.out.println("Unique Count:"+ getUniqueElements(arr));
System.out.println(Arrays.toString(arr));
}
OutPut:
Unique Count:2
[1, 3, 6, 7, 8, 0, 0, 0, 0, 0]
Since in the given array 1,7 are unique.
Note: tried with your example array {6, 10, 19, 21, 23 ,26 ,27 ,36 ,38, 45 } also
My solution is as(assuming elements can repeat only twice):
public static int removeDups(int[] arr) {
int i = 0;
int numDups = 0;
while (i < arr.length - 1 - numDups) {
if (arr[i] == arr[i + 1]) {
numDups++;
for (int m = i + 1; m < arr.length - numDups; m++) {
arr[m] = arr[m + 1];
}
arr[arr.length - numDups] = 0;
}
i++;
}
return arr.length-numDups;
}
Basically i have to return an array of n numbers repeated in an array into another array of length m.
my code so far:
public class Histogram {
public static int[] frequency(int[] a, int M) {
int[] m = new int[M];
int count = 0;
for(int j = 0; j < a.length; j++)
for(int i = 0; i < m.length; i++)
if( i == a[j]){
m[i] = count++;
}
}
return m;
} public static void main(String[] args) {
int[] a = {7, 4, 9, 1, 10, 11, 11, 1, 5, 8, 4, 2, 9, 4, 3, 9,
2, 10, 11, 7, 7, 1, 11, 3, 8, 8, 10, 4, 10, 5};
int[] b = frequency(a, 12);
for (int i = 0; i < b.length; i++) {
Std.Out.println(i + "->" + b[i]);
} } }
this is the output im supposed to get
0->0
1->3
2->2
3->2
4->4
5->2
6->0
7->3
8->3
9->3
10->4
11->4
but im getting
0->0
1->21
2->16
3->23
4->27
5->29
6->0
7->20
8->25
9->15
10->28
11->22
what am i doing wrong?
I am not going to give you a different solution, but rather to show the mistakes in your code. If we go with the logic in your code, you have few mistakes:
1) count should be reset to 0 after first loop. Otherwise you will sum up the counts from the previous iterations.
2) count++ should be before the assignment, otherwise it will first assign and then increment. Or you could use ++count.
3) The first loop should be over i.
public static int[] frequency(int[] a, int M) {
int[] m = new int[M];
int count;
for(int i = 0; i < m.length; i++) {
count =0;
for(int j = 0; j < a.length; j++)
if( i == a[j]){
count++;
m[i] = count;
}
}
return m;
}
Regards.
This should solve it and do the job!
public class Histogram {
public static int[] frequency(int[] a, int M) {
int[] m = new int[M];
for(int j = 0; j < a.length; j++) {
m[a[j]] += 1;
}
return m;
}
public static void main(String[] args) {
int[] a = {7, 4, 9, 1, 10, 11, 11, 1, 5, 8, 4, 2, 9, 4, 3, 9,
2, 10, 11, 7, 7, 1, 11, 3, 8, 8, 10, 4, 10, 5};
int[] b = frequency(a, 12);
for (int i = 0; i < b.length; i++) {
System.out.println(i + "->" + b[i]);
}
}
}
public class Histogram {
public static int[] frequency(int[] a, int M) {
int[] m = new int[M];
for(int i = 0; i < a.length; i++) //loop through a
if( i < M) //number check
m[a[i]]++; //add one to m at index a[i]
return m;
}
}
this is the right code for the method frequency, also checks to see if the number is in range.
How would one go about filling in an array so that, for example, if you had the following array.
int[] arr = new int[5];
arr[0] = 1;
arr[1] = 3;
arr[2] = 7;
arr[3] = 2;
arr[4] = -4;
so it would look like
arr = {1, 3, 7, 2, -4};
and you would pass it into your method to get a result of
arr = {1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4};
so that you essentially are filling in the numeric gaps. I'd like to make this under the assumption that I don't know how long the array passed in is going to be to make it a more universal method.
my current method looks like such right now...
public static void fillArray(int[] numbers){
int length = numbers.length;
for(int i = 0; i < numbers.length - 1; i ++){
if(numbers[i] <= numbers[i + 1]){
length += numbers[i + 1] - numbers[i];
}else if(numbers[i + 1] < numbers[i]){
length += numbers[i + 1] - numbers[i];
}
}
}
I have length to determine the size of my new array. I think it should work but I'm always down for some input and advice.
Looks like homework, providing algorithm only:
Navigate through the elements of the current array.
Get the distance (absolute difference) between the elements in the array.
Summarize the distances.
Create a new array whose length would be the sum of the distances.
Fill the new array using the elements of the first array and filling the gaps.
Return the array.
Like Luiggi Mendoza said, looks like HW, so here's another algorithm:
insert the first element into a list of integers.
loop on the rest of the elements.
for each two array elements X[i-1], X[i], insert the missing integers to the list
after the loop - use guava to turn the List to array.
This works. just check for array size < 2 for safety.
public static void main(String[] args) {
int[] arr = {1, 3, 7, 2, -4};
Integer[] result = fillArray(arr);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i]);
}
}
private static Integer[] fillArray(int[] arr) {
List<Integer> list = new ArrayList<Integer>();
list.add(arr[0]);
for (int i = 1; i < arr.length; i++) {
int prevItem = arr[i-1];
int gap = arr[i] - prevItem;
if(gap > 0){
fillGap(list, prevItem, gap, 1);
} else if(gap < 0){
fillGap(list, prevItem, gap, -1);
}
}
return list.toArray(new Integer[0]);
}
private static void fillGap(List<Integer> list, int start, int gap, int delta) {
int next = start+delta;
for (int j = 0; j < Math.abs(gap); j++) {
list.add(next);
next = next+delta;
}
}
Try
import java.util.ArrayList;
import java.util.List;
public class ArrayGap {
public static void main(String[] args) {
int[] arr = {1, 3, 7, 2, -4};
int high, low;
List<Integer> out = new ArrayList<Integer>();
for(int i=0; i<arr.length - 1; i++){
high = arr[i];
if(arr[i] < arr[i+1]){
for(int j=arr[i]; j<arr[i+1]; j++){
out.add(j);
}
} else {
for(int j=arr[i]; j>=arr[i+1]; j--){
out.add(j);
}
}
}
System.out.println(out);
}
}