I have an array of objects in Java, and I am trying to pull one element to the top and shift the rest down by one.
Assume I have an array of size 10, and I am trying to pull the fifth element. The fifth element goes into position 0 and all elements from 0 to 5 will be shifted down by one.
This algorithm does not properly shift the elements:
Object temp = pool[position];
for (int i = 0; i < position; i++) {
array[i+1] = array[i];
}
array[0] = temp;
How do I do it correctly?
Logically it does not work and you should reverse your loop:
for (int i = position-1; i >= 0; i--) {
array[i+1] = array[i];
}
Alternatively you can use
System.arraycopy(array, 0, array, 1, position);
Assuming your array is {10,20,30,40,50,60,70,80,90,100}
What your loop does is:
Iteration 1: array[1] = array[0]; {10,10,30,40,50,60,70,80,90,100}
Iteration 2: array[2] = array[1]; {10,10,10,40,50,60,70,80,90,100}
What you should be doing is
Object temp = pool[position];
for (int i = (position - 1); i >= 0; i--) {
array[i+1] = array[i];
}
array[0] = temp;
You can just use Collections.rotate(List<?> list, int distance)
Use Arrays.asList(array) to convert to List
more info at: https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#rotate(java.util.List,%20int)
Instead of shifting by one position you can make this function more general using module like this.
int[] original = { 1, 2, 3, 4, 5, 6 };
int[] reordered = new int[original.length];
int shift = 1;
for(int i=0; i<original.length;i++)
reordered[i] = original[(shift+i)%original.length];
Just for completeness: Stream solution since Java 8.
final String[] shiftedArray = Arrays.stream(array)
.skip(1)
.toArray(String[]::new);
I think I sticked with the System.arraycopy() in your situtation. But the best long-term solution might be to convert everything to Immutable Collections (Guava, Vavr), as long as those collections are short-lived.
Manipulating arrays in this way is error prone, as you've discovered. A better option may be to use a LinkedList in your situation. With a linked list, and all Java collections, array management is handled internally so you don't have to worry about moving elements around. With a LinkedList you just call remove and then addLast and the you're done.
Try this:
Object temp = pool[position];
for (int i = position-1; i >= 0; i--) {
array[i+1] = array[i];
}
array[0] = temp;
Look here to see it working: http://www.ideone.com/5JfAg
Using array Copy
Generic solution for k times shift k=1 or k=3 etc
public void rotate(int[] nums, int k) {
// Step 1
// k > array length then we dont need to shift k times because when we shift
// array length times then the array will go back to intial position.
// so we can just do only k%array length times.
// change k = k% array.length;
if (k > nums.length) {
k = k % nums.length;
}
// Step 2;
// initialize temporary array with same length of input array.
// copy items from input array starting from array length -k as source till
// array end and place in new array starting from index 0;
int[] tempArray = new int[nums.length];
System.arraycopy(nums, nums.length - k, tempArray, 0, k);
// step3:
// loop and copy all the remaining elements till array length -k index and copy
// in result array starting from position k
for (int i = 0; i < nums.length - k; i++) {
tempArray[k + i] = nums[i];
}
// step 4 copy temp array to input array since our goal is to change input
// array.
System.arraycopy(tempArray, 0, nums, 0, tempArray.length);
}
code
public void rotate(int[] nums, int k) {
if (k > nums.length) {
k = k % nums.length;
}
int[] tempArray = new int[nums.length];
System.arraycopy(nums, nums.length - k, tempArray, 0, k);
for (int i = 0; i < nums.length - k; i++) {
tempArray[k + i] = nums[i];
}
System.arraycopy(tempArray, 0, nums, 0, tempArray.length);
}
In the first iteration of your loop, you overwrite the value in array[1]. You should go through the indicies in the reverse order.
static void pushZerosToEnd(int arr[])
{ int n = arr.length;
int count = 0; // Count of non-zero elements
// Traverse the array. If element encountered is non-zero, then
// replace the element at index 'count' with this element
for (int i = 0; i < n; i++){
if (arr[i] != 0)`enter code here`
// arr[count++] = arr[i]; // here count is incremented
swapNumbers(arr,count++,i);
}
for (int j = 0; j < n; j++){
System.out.print(arr[j]+",");
}
}
public static void swapNumbers(int [] arr, int pos1, int pos2){
int temp = arr[pos2];
arr[pos2] = arr[pos1];
arr[pos1] = temp;
}
Another variation if you have the array data as a Java-List
listOfStuff.add(
0,
listOfStuff.remove(listOfStuff.size() - 1) );
Just sharing another option I ran across for this, but I think the answer from #Murat Mustafin is the way to go with a list
public class Test1 {
public static void main(String[] args) {
int[] x = { 1, 2, 3, 4, 5, 6 };
Test1 test = new Test1();
x = test.shiftArray(x, 2);
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
}
public int[] pushFirstElementToLast(int[] x, int position) {
int temp = x[0];
for (int i = 0; i < x.length - 1; i++) {
x[i] = x[i + 1];
}
x[x.length - 1] = temp;
return x;
}
public int[] shiftArray(int[] x, int position) {
for (int i = position - 1; i >= 0; i--) {
x = pushFirstElementToLast(x, position);
}
return x;
}
}
A left rotation operation on an array of size n shifts each of the array's elements unit to the left, check this out!!!!!!
public class Solution {
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
String[] nd = scanner.nextLine().split(" ");
int n = Integer.parseInt(nd[0]); //no. of elements in the array
int d = Integer.parseInt(nd[1]); //number of left rotations
int[] a = new int[n];
for(int i=0;i<n;i++){
a[i]=scanner.nextInt();
}
Solution s= new Solution();
//number of left rotations
for(int j=0;j<d;j++){
s.rotate(a,n);
}
//print the shifted array
for(int i:a){System.out.print(i+" ");}
}
//shift each elements to the left by one
public static void rotate(int a[],int n){
int temp=a[0];
for(int i=0;i<n;i++){
if(i<n-1){a[i]=a[i+1];}
else{a[i]=temp;}
}}
}
You can use the Below codes for shifting not rotating:
int []arr = {1,2,3,4,5,6,7,8,9,10,11,12};
int n = arr.length;
int d = 3;
Programm for shifting array of size n by d elements towards left:
Input : {1,2,3,4,5,6,7,8,9,10,11,12}
Output: {4,5,6,7,8,9,10,11,12,10,11,12}
public void shiftLeft(int []arr,int d,int n) {
for(int i=0;i<n-d;i++) {
arr[i] = arr[i+d];
}
}
Programm for shifting array of size n by d elements towards right:
Input : {1,2,3,4,5,6,7,8,9,10,11,12}
Output: {1,2,3,1,2,3,4,5,6,7,8,9}
public void shiftRight(int []arr,int d,int n) {
for(int i=n-1;i>=d;i--) {
arr[i] = arr[i-d];
}
}
import java.util.Scanner;
public class Shift {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
int array[] = new int [5];
int array1[] = new int [5];
int i, temp;
for (i=0; i<5; i++) {
System.out.printf("Enter array[%d]: \n", i);
array[i] = input.nextInt(); //Taking input in the array
}
System.out.println("\nEntered datas are: \n");
for (i=0; i<5; i++) {
System.out.printf("array[%d] = %d\n", i, array[i]); //This will show the data you entered (Not the shifting one)
}
temp = array[4]; //We declared the variable "temp" and put the last number of the array there...
System.out.println("\nAfter Shifting: \n");
for(i=3; i>=0; i--) {
array1[i+1] = array[i]; //New array is "array1" & Old array is "array". When array[4] then the value of array[3] will be assigned in it and this goes on..
array1[0] = temp; //Finally the value of last array which was assigned in temp goes to the first of the new array
}
for (i=0; i<5; i++) {
System.out.printf("array[%d] = %d\n", i, array1[i]);
}
input.close();
}
}
Write a Java program to create an array of 20 integers, and then implement the process of shifting the array to right for two elements.
public class NewClass3 {
public static void main (String args[]){
int a [] = {1,2,};
int temp ;
for(int i = 0; i<a.length -1; i++){
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
for(int p : a)
System.out.print(p);
}
}
I need to implement this algorithm creating a new ArrayList object at each recursive call.
My starting Array contains integers in this order"20, 40 ,10, 30 ,50 ,5" , after sorting it I have 5,5,5,5,5,5. I think that the problem is in the recursive call and in the last for cicle of the SelectionSort because removing the last for I notice that the the first element is sorted correctly.
import java.util.*;
public class SelectionSort {
//var
public ArrayList<Integer> arr ;
//constructor
public SelectionSort(ArrayList<Integer> arr){
this.arr = arr;
}
public ArrayList<Integer> getarraylist() {
return arr;
}
public void sort(){
//position of the last sorted element
int minimum =0;
if (arr.size() <=0 ) return;
for ( int j = 1; j < arr.size()-1; j++ ) {
if (arr.get(j) < arr.get(0) ) {
minimum = j;
//swap element 0 and minimum
int temp = arr.get(0);
arr.set(0, arr.get(minimum));
arr.set(minimum, temp);
}
}
//recursive call, new array without first element (already sorted)
ArrayList<Integer> arr2 = new ArrayList<>(arr.subList(1,arr.size()));
SelectionSort s2 = new SelectionSort(arr2);
s2.sort();
for(int i=0;i<s2.getarraylist().size();i++) {
arr.set(i, s2.getarraylist().get(i));
}
}
Driver class
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<Integer (Arrays.asList(20,40,10,30,50,5));
System.out.println("\n ARRAY ELEMENTS \n ");
for (int i: arr) {
System.out.println(i);
}
System.out.println("\n SORTED ELEMENTS \n ");
SelectionSort s = new SelectionSort(arr);
s.sort();
for (int i: s.getarraylist()) {
System.out.println(i);
}
}
}
You have actually two bugs in your algorithm that, together, lead to the observed output.
The first bug is within the for-loop that determines the minimal element:
for ( int j = 1; j < arr.size()-1; j++ ) { ...
You terminate one element too early, i.e. the last element is never considered. Thus, after the first iteration, the 5 is the last element in your ArrayList. In fact, it is the last element in every of your ArrayLists. The fix is to not subtract 1 in the for-condition:
for ( int j = 1; j < arr.size(); j++ ) { ...
The second bug is in your last for-loop where you copy the values from index i of s2 to index i of arr. You neglect the fact that s2 is one element shorter than arr. Thus, the only element not overriden is the last element. The fix is to get the i-th element from s2, but write it at the i + 1-th index of arr:
arr.set(i + 1, s2.getarraylist().get(i));
Now let us take look at how those two bugs lead to the observed output. Since
the last element in your ArrayList is never overridden and
the last element is always the same,
all elements have the same value (in your test case: 5).
Some remarks on your code:
the variable minimum is superfluous and can be replaced with j.
If you replace all occurences of ArrayList in SelectionSort with List, you can actually simplify the last part of your code to:
// remove the line declaring arr2, it is no longer needed
SelectionSort s2 = new SelectionSort(arr.subList(1, arr.size()));
s2.sort();
// last for-loop not needed anymore, method ends here
This is possible because ArrayList#subList(...) states that "The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa."
You should take a little bit more care wrt. indentation.
You have some minor inconsistencies in your coding style. For example, sometimes you write a blank after ( or before a ) or {, sometimes you do not. See what you like more and use it uniformly.
In Java, variable-, parameter- and methodnames should be written in camelCase (getarraylist() -> getArrayList())
With your last loop:
for(int i=0;i<s2.getarraylist().size();i++) {
arr.set(i, s2.getarraylist().get(i));
}
This overrides every element with the same number. (Why you got all 5's as your result) This is because you only iterate to the second to last element (arr.size()-1). Then you copy the elements in the line:
ArrayList<Integer> arr2 = new ArrayList<>(arr.subList(1,arr.size()));
Eventually you are only copying the last element over (5) and then copying this to the final ArrayList arr.
Also you create another SelectionSort object every time you call the sort method. This is not good.
Here is the code I wrote:
public void sort(List<Integer> list){
//position of the last ordered element
int minimum =0;
if (list.size() <=0 ) return;
for ( int j = 1; j < list.size(); j++ ) {
if (list.get(j) < list.get(0) ) {
minimum = j;
//swap element 0 and minimum
int temp = list.get(0);
list.set(0, list.get(minimum));
list.set(minimum, temp);
}
}
sort(list.subList(1,list.size()));
}
I changed it to accept an argument of List<Integer> (Because the subList() method returns a List) and then got rid of the last loop and where you created new objects.
Also youll have to change
s.sort();
to:
s.sort(s.getarraylist());
Output:
ARRAY ELEMENTS
20
40
10
30
50
5
SORTED ELEMENTS
5
10
20
30
40
50
Im not sure I understand the question, but I created a recursive (and iterative) selectionSort and InsertionSort just for fun, hope it helps.
public class Sorts {
public static void swap(Comparable[] a, int i, int j) {
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void selectionSortItr(Comparable[] a, int n) {
for (int i = 0; i < n - 1; i++) {
int f = i;
for (int j = i + 1; j < n; j++) {
if (a[j].compareTo(a[f]) < 0)
f = j;
}
swap(a, i, f);
}
}
public static int select(Comparable[] a, int n, int j, int f) {
if (j >= n)
return f;
if (a[j].compareTo(a[f]) < 0)
f = j;
return select(a, n, j + 1, f);
}
public static void selectionSort(Comparable[] a, int n, int i) {
if (i < n - 1) {
swap(a, i, select(a, n, i + 1, i));
selectionSort(a, n, i + 1);
}
}
public static void insertionSortItr(Comparable[] a) {
for (int i = 1; i < a.length; i++) {
int j;
Comparable cur = a[i];
for (j = i; j > 0 && cur.compareTo(a[j - 1]) < 0; j--) {
a[j] = a[j - 1];
}
a[j] = cur;
}
}
public static void insertionSortInner(Comparable[] a, Comparable cur, int j) {
if (j > 0 && cur.compareTo(a[j - 1]) < 0) {
a[j] = a[j - 1];
insertionSortInner(a, cur, j - 1);
} else {
a[j] = cur;
}
}
public static void insertionSort(Comparable[] a, int i, int n) {
if (i < n) {
insertionSortInner(a, a[i], i);
insertionSort(a, i + 1, n);
}
}
public static void main(String[] args) {
Integer[] a = new Integer[10];
for (int i = 0; i < 10; i++)
a[i] = (int) (Math.random()*100);
selectionSort(a, 10, 0);
for (int i = 0; i < 10; i++)
System.out.println(a[i]);
}
}
I need to implement the following in java.
Input: an array of integers
Output: Rearrange the array to have the following:
Suppose the first element in the original array has the value x
In the new array, suppose that x is in position I, that is data[I] = x. Then, data[j] <= x for all x and for all j > I. This means that all the values to the "left" of x are less than or equal to x and all the values to the "right" are larger than x.
An example is as follows: Suppose the array has the elements in this initial order: 4,3,9,2,7,6,5. After applying your algorithm, you should get: 3,2,4,5,9,7,6. That is, the leftmost element, 4, is positioned in the resulting array so that all elements less than 4 (2 and 3) are to its left (in no particular order), and all elements larger than 4 are to its right (in no particular order).
There is no space requirement for the algorithm, only that the problem is solved in O(n) time.
I have implemented a bucket sort, but am having some difficulties with the code.
public class Problem4
{
public static void partition(int[] A)
{
int x = A[0];
int l = A.length;
int[] bucket = int [];
for(int i=0; i<bucket.length; i++){
bucket[i]=0;
}
for (int i=0; i<l; i++){
bucket[x[i]]++;
}
int outPos=0;
for(int i=0; i<bucket.length; i++){
for(int j=0; j<bucket[i]; j++){
x[outPos++]=i;
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] A = {4,3,9,2,7,6,5};
System.out.println("Before partition:");
for(int i = 0; i < A.length; i++)
{
System.out.print(A[i] + " ");
}
partition(A);
System.out.println("After partition:");
System.out.println("Before partition:");
for(int i = 0; i < A.length; i++)
{
System.out.print(A[i] + " ");
}
}
}
The lines:
int[] bucket = int[],
bucket[x[i]]++;, and
x[outpost++] = i;
are causing me troubles. I am getting the error
The type of expression must be an array type but is resolved to an int.
The problem stems from that first line where I am trying to create a new array called bucket. I would appreciate any suggestions! Thanks!
I don't think you need to resort to a bucket sort. Instead you can simply walk through the array, placing elements that are less than the split value at the front and elements that are greater at the back. We can use two variables, front and back to keep track of the insert position at the front and back of the array. Starting at position 1 in the array, if the value is less than the split value we place at front and increment front and the current index. If the value is greater we swap it with the value at back and decrement back, but we keep the current index.
Here's some code to illustrate:
public static void main(String[] args)
{
int[] A = {4,3,9,2,7,6,5};
sort(A);
System.out.println(Arrays.toString(A));
}
public static void sort(int[] arr)
{
int split = arr[0];
int front = 0;
int back = arr.length-1;
for(int i=1; front != back; )
{
if(arr[i] <= split)
{
arr[front] = arr[i];
front += 1;
i++;
}
else
{
swap(arr, i, back);
back -= 1;
}
}
arr[front] = split;
}
public static void swap(int[] arr, int i, int j)
{
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
Output:
[3, 2, 4, 7, 6, 5, 9]
Another approach you can use is to use the standard partition algorithm of QuickSort.
I have modified your code and the following code
public class Problem4
{
/* This function takes last element as pivot,
places the pivot element at its correct
position in sorted array, and places all
smaller (smaller than pivot) to left of
pivot and all greater elements to right
of pivot */
public static int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low-1); // index of smaller element
for (int j=low; j<high; j++)
{
// If current element is smaller than or
// equal to pivot
if (arr[j] <= pivot)
{
i++;
// swap arr[i] and arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// swap arr[i+1] and arr[high] (or pivot)
int temp = arr[i+1];
arr[i+1] = arr[high];
arr[high] = temp;
return i+1;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] A = {4,3,9,2,7,6,5};
System.out.println("Before partition:");
for(int i = 0; i < A.length; i++)
{
System.out.print(A[i] + " ");
}
// swap and call the standard partition algo of QuickSort
// on last element pivot. swap arr[low] and arr[high]
int low = 0;
int high = A.length-1;
int temp = A[low];
A[low] = A[high];
A[high] = temp;
partition(A, low, high);
System.out.println("\nAfter partition:");
for(int i = 0; i < A.length; i++)
{
System.out.print(A[i] + " ");
}
}
}
Outputs
Before partition:
4 3 9 2 7 6 5
After partition:
3 2 4 5 7 6 9
Hope it helps!