I need to make this insertion sort function essentially copy elements to the right until the value that needs to be moved would be in the correct position, however, with the code I'm using I typically end up getting garbage out, and have tried multiple iterations with the same result. I am at wits end as I see no reason why this shouldn't work.
public static void Sort(Comparable[] a) {
int n = a.length;
Comparable temp = 0;
int x;
// Starting with the element at index 1...
for (int i = 1; i < n; i++) {
// ...move to the left until we find one less
// than the current element.
for (int j = i; j > 0; j--) {
if (less(a[j], a[j - 1]))
{
temp = a[j];
for(x = j; x > 0 && less(temp, a[x]); x--)
{
a[x] = a[x - 1];
}
a[x] = temp;
//exch(a, j, j - 1);
}
else
break;
}
}
}
less(a, b) checks to see if a < b, by the way.
On the first iteration of the innermost loop, in this condition: x > 0 && less(temp, a[x]) you are checking whether the value you just stored in temp... is less than the value you just stored in temp, referred to by another name. This will always return false, causing the loop to never start. The end result is that the entire method is an expensive no-op. If you're testing it by sending in a randomly jumbled array, you'll end up with the array still randomly jumbled when it's done.
To fix this, simply subtract 1 from the index in that condition, making it x > 0 && less(temp, a[x - 1]).
The rest of your code looks correct, I think, though the loop with j is redundant and can be removed.
This should do the trick
public static void Sort(Comparable[] a) {
int n = a.length;
Comparable temp = 0;
int x;
// Starting with the element at index 1...
for (int i = 1; i < n; i++) {
// ...move to the left until we find one less
// than the current element.
for (int j = i; j > 0; j--) {
if (less(a[j], a[j - 1]))
{
temp = a[j];
for(x = j; x > 0 && less(temp, a[x-1]); x--)
{
a[x] = a[x - 1];
}
a[x] = temp;
//exch(a, j, j - 1);
}
else
break;
}
}
}
Related
Here is the code:
public static int MaxProduct(int... a){ // the max possible product from an array
int i = 0;
int j = 0;
int m = 0;
int n = a.length;
while (i<n){
j++;
while(j<n ){
if (a[i]*a[j] > m){
m = a[i]*a[j];
j++;
}
}
i++;
}
return m;
}
System.out.println(MaxProduct(1,2,3,4,5));
The algorithm seems to work as expected (after check and making a table of the debugger). For the first index of an array it checks all possible products and edits m accordingly from 1 through to 5. And then once j is equal to 5 a[j]understandably is out of bounds since there are only 5 elements in the array
I then see the arrayoutofbounds error in the debugger beside (again which is what id expect) but instead of i increasing, and the second while loop starting the cycle again, a[i] stays as 1, the algorithm concludes, and i get the output 5
How do i get this to output 20 (4x5)
You need to make two changes. Check below 2 TODOs.
public static int MaxProduct(int... a) { // the max possible product from an array
int i = 0;
int j = 0;
int m = 0;
int n = a.length;
while (i < n) {
j = i + 1; // TODO: 1
while (j < n) {
if (a[i] * a[j] > m) {
m = a[i] * a[j];
}
j++; // TODO:2
}
i++;
}
return m;
}
Given a binary array, find the number of minimum adjacent swaps needed to group 1's and 0's.
Example:
Input : 0,1,0,1 (array with 0 based index)
Swaps needed : 0,1,0,1 -> 0,0,1,1 (1 swap from index 1 to index 2)
Solution : 1
Exmaple:
Input : 1,0,1,0,0,0,0,1
Swaps needed :
1,0,1,0,0,0,0,1 -> 1,1,0,0,0,0,0,1 -> 1,1,0,0,0,0,1,0 -> 1,1,0,0,0,1,0,0 -> 1,1,0,0,1,0,0,0 -> 1,1,0,1,0,0,0,0 -> 1,1,1,0,0,0,0,0
Total 6 swaps so the solution is 6.
The 1's and 0's can be positioned at the beginning or end but they should be at a single place i.e. either begin or end.
I have come up with below logic for this requirement. I tried this in a hackerrank, it failed for a single hidden test case and gave timeout for 3 test cases as I have nested loops in my code.
static int countSwaps(List<Integer> list) {
int temp;
int swaps = 0;
int n = list.size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
if ((list.get(j) == 0) && (list.get(j + 1) == 1)) {
temp = list.get(j);
list.set(j, list.get(j + 1));
list.set(j + 1, temp);
swaps++;
}
}
}
return swaps;
}
What is a better approach to solving this program?
I have already gone through this post Given an array of 0 and 1, find minimum no. of swaps to bring all 1s together (only adjacent swaps allowed) but the answers are not giving correct output.
Building on answer by Gene, fixing the compile error and supporting moving 1's to the left (to the beginning) or moving them to the right (to the end), aka moving 0's to the left:
static int countSwaps(int... a) {
int n0 = 0, i0 = 0, n1 = 0, i1 = 0;
for (int p = 0; p < a.length; ++p) {
if (a[p] == 0)
n0 += p - i0++; // No. of steps to move the 0 to the left
else
n1 += p - i1++; // No. of steps to move the 1 to the left
}
return Math.min(n0, n1); // Choose lowest no. of steps
}
Test
System.out.println(countSwaps(0,1,0,1));
System.out.println(countSwaps(1,0,1,0,0,0,0,1));
System.out.println(countSwaps(1,0,0,0,0,1,0,1));
Output
1
6
6
To move all 1's to the left, let p(i) be the position of i'th 1 from left to right. It ultimately needs to move to position i. This will need p(i) - i swaps. Just sum up this quantity for all i.
int countSwaps(int [] a) {
int n = 0, i = 0;
for (int p = 0; p < a.length; ++p)
if (a[p] == 1) {
n += p - i;
++i;
}
return n;
}
Moving to the right is symmetric. Do a similar computation and take the min.
Here is my solution (Java):
public static int minSwaps(int[] arr) {
int min_swaps1 = 0;
int zero_counts = 0;
int min_swaps2 = 0;
int one_counts = 0;
for (int j : arr) {
if (j == 0) {
zero_counts++;
min_swaps2 += one_counts;
} else {
one_counts++;
min_swaps1 += zero_counts;
}
}
return Math.min(min_swaps1, min_swaps2);
}
i want to implement a selection sort method that takes an array of ints and sorts it in a descending order. however, the trick is to keep the original selection sort method unchanged but instead using simple arithmetic operations and without adding extra loops to swap the elements after the array finished sorting. this is my code and the idea is to store the position of the maximum value and the minimum value in local variables and swap them with the corresponding position after the inner loop finishes iteration. i even tried using a only one variable to find the lowest value and put it at the end of the array but i failed and i am getting the wrong results and i need help spotting the error. here is my code
public static void newSortMethod(int[]a){
for(int i = 0; i < a.length-1; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < a.length; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
if(a[j] > a[maxPosition]){
maxPosition = j;
}
}
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
System.out.println();
}
public static void swap(int[]a, int i, int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void main(String[] args) {
int[] a = {2,6,3,9,5,4,8,7,0,13,-3,1};
newSortMethod(a);
}
here is the output of the program so far
-3 8 2 9 13 5 4 6 3 1 7 0
Your original algorithm is wrong. Firstly, the if blocks should compare to minPosition and maxPosition, not i. Secondly, if you are selecting both minimum and maximum, then your inner for loop should stop at a.length - i, not a.length (since the top i elements are also sorted). Doing both gives you this as the ascending order algorithm.
public static void newSortMethod(int[]a){
for(int i = 0; i < a.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < a.length - i; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
if(a[j] > a[maxPosition]){
maxPosition = j;
}
}
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
}
To switch to descending order, simply add one line.
public static void newSortMethod(int[]a){
for(int i = 0; i < a.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < a.length - i; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
if(a[j] > a[maxPosition]){
maxPosition = j;
}
}
swap(a,minPosition,maxPosition); // <-- this line
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
}
Errors
First off, let’s look for problems in your code. There’s a few, which happens a lot in programming.
Your code is still trying to sort ascending with swap(a,minPosition,i), and then trying to put the maximum value at the end, which isn’t what you want: you want to put maximum values at the beginning.
Your n is never modified, so you’ll keep printing 0.
Sample solution
Now let’s see something that works. I’m not totally sure what your ascending selection sort looked like, but I imagine it should be something like this:
public static void ascendingSortMethod(int[]a){
int n = 0; // this is only to count how many times the swap method was called
for(int i = 0; i < a.length-1; i++){
int minPosition = i;
for(int j = i+1; j < a.length; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
}
if(minPosition != i){ // check whether swap is necessary
swap(a,minPosition,i);
n ++;
}
}
System.out.println(n);
}
To make it sort in descending order, just switch the comparison operator (and possibly the minPosition identifier for clarity).
public static void newSortMethod(int[]a){
int n = 0; // this is only to count how many times the swap method was called
for(int i = 0; i < a.length-1; i++){
int maxPosition = i;
for(int j = i+1; j < a.length; j++){
if(a[j] > a[maxPosition]){ // switched comparison operator
maxPosition = j;
}
}
if(maxPosition != i){ // check whether swap is necessary
swap(a,maxPosition,i);
n ++;
}
}
System.out.println(n);
}
I´m working on insertion sorting a bunch of numbers but I just can´t wrap my head around it. I´m pretty sure the "j = i - 1" is wrong and a bunch of other things, and I´d really appreciate it if you guys could point out my mistakes so I can fix them.
public class temp {
public static void main(String[] args) {
int numbrid[] = {2, 5, 9, 7, 1, 4, 3, 8, 6};
System.out.println("before:");
int i, j, k;
for (i = 0; i < numbrid.length; i++) {
System.out.println(numbrid[i]);
}
//sorting
System.out.println("after:");
for (i = 1; i < numbrid.length; i++) {
j = i - 1;
while (numbrid[i] < numbrid[j]) {
k = numbrid[i];
numbrid[i] = numbrid[j];
numbrid[j] = k; // swaps their places
}
}
for ( i = 0; i < numbrid.length; i++ ) {
System.out.println(numbrid[i]);
}
}
}
Edit: all this does is it takes the largest number and brings it to the bottom
A few problems in your for loop:
Insertion has to use just 1 input per iteration (of the outside for), hence you have to assign the value to your temp variable before you get into your while
for (i = 1; i < numbrid.length; i++) {
k = numbrid[i];
Step on to the while loop with replacing the next number with the previous one till you reach your temp number (till your numbrid[j] > k)
while ((j > -1) && (numbrid[j] > k)) {
numbrid[j + 1] = numbrid[j];
j--;
}
Assign your temp value to the next element in your array
numbridj + 1] = k;
Move on with your for loop
Hence, your for loop becomes:
...
for (i = 1; i < numbrid.length; i++) {
k = numbrid[i];
j = i - 1;
while ((j > -1) && (numbrid[j] > k)) {
numbrid[j + 1] = numbrid[j];
j--;
}
numbrid[j + 1] = k;
}
...
I see two errors:
You musn't swap j and i elements but j and j+1
You are forgetting to decrease j
oooh #PopoFibo anticipated :( well I'll post anyway..
Sorry if its a basic question...
I am just trying to learn more on algorithms...
I wrote a simple code to perform insertion sort in ascending order, but for some reason I couldn't make it work to perform sort in descending order.
I tried changing the comparison key (while (i > 0 && a[i] > key) to (i > 0 && a[i] < key)).. it seems to work partially but the first element is not getting sorted, I get the below results..Can someone let me know where I am wrong?
1
11
10
9
5
4
3
2
public class InsertionSort {
public static void main(String args[]) {
int[] a = { 1,10,11,5, 9, 3, 2, 4 };
// Loop through the entire array length. Consider you already have one
// element in array, start comparing with
// first element
for (int j = 1; j < a.length; j++) {
// Get the key (The value that needs to be compared with existing
// values.
int key = a[j];
// Get the array index for comparison, we need to compare with all
// other elements in the array with
// key
int i = j - 1;
// While i > 0 and when key is less than the value in the array
// shift the value and insert
// the value appropriately.
//System.out.println(j);
while (i > 0 && a[i] < key) {
a[i + 1] = a[i];
i = i - 1;
a[i + 1] = key;
}
}
for (int k = 0; k < a.length; k++) {
System.out.println(a[k]);
}
}
}
You're never touching a[0] in
while (i > 0 && a[i] < key) {
so it isn't sorted into its due place. Use >= instead of >:
while (i >= 0 && a[i] < key) {
The same problem would occur when sorting in ascending order.
The first element in the array is a[0]. You're not comparing it anywhere.
Start from 0 with array a[] to reach the first element a[0]. So first element in a[j] will be a[0] and not a[1];
public static void insertionSort(int[] arr)
{
for (int i = 1; i < arr.length; i++)
{
int curNumber = arr[i];
int curIndex = i-1;
while ( curIndex >= 0 && arr[curIndex] < curNumber)
{
arr[curIndex+1] = arr[curIndex];
curIndex--;
}
arr[curIndex+1] = curNumber;
}
}