Why isn't my selection sort program working? - java

I am trying to create my own program to do selection sort on an array of integers. I have come up with the following program, which works on some arrays, but not on others, such as this one. I have been trying to trace the problem, and I think it might have to do with where I am placing the min = num [x]; line. However, I am not sure where I should move it in order to fix the problem. Does anyone have any suggestions? Thank you.
p.s. I have provided some of my test cases and their results at the bottom.
int [] num = {4, 9, 7, 6, 0, 1, 3, 5, 8, 2};
int min = num [0];
int temp;
int index = 0;
for (int x = 0; x < num.length; x ++)
{
min = num [x];
temp = num [x];
for (int y = x + 1; y < num.length; y ++)
{
if (num [y] < min)
{
min = num [y];
index = y;
}
}
num [x] = min;
num [index] = temp;
min = num [x];
}
Output Test Cases:
array: {4, 9, 7, 6, 0, 1, 3, 5, 8, 2}
result: [0, 1, 2, 3, 4, 4, 5, 7, 8, 8]
array: {7, 5, 8, 9, 1, 6, 3, 0, 2, 4}
result: [0, 1, 2, 3, 4, 5, 6, 7, 7, 8]
array: {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
result: [0, 1, 2, 3, 4, 9, 6, 7, 8, 9]

there is one big problem and multiple small ones, see comments:
int [] num = {4, 9, 7, 6, 0, 1, 3, 5, 8, 2};
int min = num [0]; // you don't need this variable and assignment here, you can declare it inside loop
int temp; // the same for this variable
int index = 0; // the same here
for (int x = 0; x < num.length; x ++)
{
min = num [x];
temp = num [x];
// here you need to re-initialize index variable to some value, otherwise it could be some garbage from previous iterations
for (int y = x + 1; y < num.length; y ++)
{
if (num [y] < min)
{
min = num [y];
index = y;
}
}
num [x] = min;
num [index] = temp;
min = num [x]; // this assignment does not make sense as you're overwriting it next iteration
}
you can simplify code a little bit:
for (int x = 0; x < num.length; x++) {
int index = x;
for (int y = x + 1; y < num.length; y++)
if (num[y] < num[index])
index = y;
int temp = num[x];
num[x] = num[index];
num[index] = temp;
}

Related

Why is my selection sort program not giving the correct output for the last few numbers?

I've been going through this MOOC.fi Java course and got to the problem about developing a selection sort algorithm on this page (https://java-programming.mooc.fi/part-7/2-algorithms). I don't have the solutions, so I was wondering if anyone here could help me solve this problem. Basically, I got through all the steps uptil Part 4, but when I tried to make the selection sort method, my method only sorted the numbers correctly until it got to the second to last number, and then it started switching the numbers incorrectly. Can anyone look over my code and tell me where I went wrong?
import java.util.Arrays;
public class MainProgram {
public static void main(String[] args) {
// Testing methods
// Test Part 1
int[] numbers = {6, 5, 8, 7, 11};
System.out.println("Smallest: " + MainProgram.smallest(numbers));
// Testing Part 2
System.out.println("Index of the smallest number: " + MainProgram.indexOfSmallest(numbers));
// Testing Part 3
System.out.println(MainProgram.indexOfSmallestFrom(numbers, 0));
System.out.println(MainProgram.indexOfSmallestFrom(numbers, 1));
System.out.println(MainProgram.indexOfSmallestFrom(numbers, 2));
// Testing Part 4
int[] numbers2 = {3, 2, 5, 4, 8};
System.out.println(Arrays.toString(numbers2));
MainProgram.swap(numbers2, 1, 0);
System.out.println(Arrays.toString(numbers2));
MainProgram.swap(numbers2, 0, 3);
System.out.println(Arrays.toString(numbers2));
// Testing Part 5
int[] numbers3 = {8, 3, 7, 9, 1, 2, 4};
MainProgram.sort(numbers3);
}
// Part 1
public static int smallest(int[] array) {
int smallest = array[0];
for (int i = 0; i < array.length; i++) {
if (array[i] < smallest) {
smallest = array[i];
}
}
return smallest;
}
// Part 2
public static int indexOfSmallest(int[] array){
int smallest = array[0];
int i;
int finalIndex = 0;
for (i = 0; i < array.length; i++) {
if (array[i] < smallest) {
smallest = array[i];
finalIndex = i;
}
}
return finalIndex;
}
// Part 3
public static int indexOfSmallestFrom(int[] table, int startIndex) {
int smallest = table[startIndex];
int i = startIndex;
int finalIndex = 0;
for (i = startIndex; i < table.length; i++) {
if (table[i] < smallest) {
smallest = table[i];
finalIndex = i;
}
}
return finalIndex;
}
// Part 4
public static void swap(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
// Part 5
public static void sort(int[] array) {
int smallestIndex;
for (int i = 0; i < array.length; i++) {
smallestIndex = indexOfSmallestFrom(array, i);
swap(array, smallestIndex, i);
System.out.println(Arrays.toString(array));
}
}
}
Here is the wrong output:
[1, 3, 7, 9, 8, 2, 4]
[1, 2, 7, 9, 8, 3, 4]
[1, 2, 3, 9, 8, 7, 4]
[1, 2, 3, 4, 8, 7, 9]
[1, 2, 3, 4, 7, 8, 9]
[8, 2, 3, 4, 7, 1, 9]
[9, 2, 3, 4, 7, 1, 8]
In the 3 block you set the
finalIndex = 0;
It should be set to the startIndex

Move a certain number to the front of an array (Java)

I need help with a code where I have to put the number "7" at the front of the array using a random array of numbers. I use Math.random to generate the random numbers in each index. In any of these indexes, a number 7 may be generated.
import java.util.Arrays;
public class NumberShifter {
public static int[] Array(){
int[] array = new int[20];
int max = 10;
int min = 1;
int rand = 0;
int range = max - min +1;
for(int t = 0;t<=array.length-1;t++) {
rand = (int)(Math.random() * range) + min;
array[t] = rand;
}
return array;
}
}
Here's an example output for the code I have displayed (its all random numbers)
[9, 6, 3, 4, 4, 10, 7, 5, 2, 10, 3, 1, 8, 7, 4, 4, 10, 5, 9, 1]
There are two sevens in this array that have been generated randomly.
I would like to have the output where the sevens are at the front.
[7, 7, 3, 4, 4, 10, 9, 5, 2, 10, 3, 1, 8, 6, 4, 4, 10, 5, 9, 1]
How would I write the rest of my code so that I can achieve this?
P.S. I'm also in high school, so I'm sorry if I get something wrong!
Iterate the elements of the array and if they are 7 swap them with the next element at the beginning of the array, using another variable to keep track of the next index for swapping.
int index = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == 7) {
int tmp = array[i]; // actually not needed, we know it's 7
array[i] = array[index];
array[index] = tmp; // or just 7
index++;
}
}
I would actually start at the end and reserve the front for the sevens.
public static int[] Array() {
int[] array = new int[20];
int max = 10;
int min = 1;
int rand = 0;
int range = max - min + 1;
int sevensGoHere = 0;
for (int t = array.length - 1; t >= sevensGoHere;) {
rand = (int) (Math.random() * range) + min;
if (rand == 7) {
array[sevensGoHere++] = rand;
}
else {
array[t--] = rand;
}
}
return array;
}
By doing it on the fly you don't need to rearrange the array.

Replace every element with next greatest element (in ascending order, not replacing with -1)

Currently working on an algorithm that replaces every element with the next greatest element, but unlike some other questions here, this one is not concerned with replacing values with -1 if no such number exists, and it must be in ascending order.
Given this input: {1, 5, -3, 2, 8, 4, 7, 10, 3, 11, 2 }
Have to get this output: 1 5 5 5 8 8 8 10 10 11 11
This is what I have so far:
class Playground {
static void nextGreatest(int arr[]) {
int size = arr.length;
// Initialize the next greatest element
int max_from_right = arr[size - 1];
// Replace all other elements with the next greatest
for (int i = 1; i < size; i++)
{
// Store the current element (needed later for
// updating the next greatest element)
int temp = arr[i];
// Replace current element with the next greatest
arr[i] = max_from_right;
// Update the greatest element, if needed
if(max_from_right < temp) {
max_from_right = temp;
}
}
}
// prints the array
static void printArray(int arr[])
{
for (int i=0; i < arr.length; i++)
System.out.print(arr[i]+" ");
}
public static void main (String[] args) {
int arr[] = {1, 5, -3, 2, 8, 4, 7, 10, 3, 11, 2 };
nextGreatest (arr);
printArray (arr);
}
}
And I get the following right now:
1 2 5 5 5 8 8 8 10 10 11
Thoughts?
Thanks
(Not sure I understand your question exactly, but based on the clarification from the comments here is my answer...)
Seems you just need to change the initial max initialization to the first element rather than the last element.
int currentMax = arr[0];
for (int i = 1; i < size; i++) {
int temp = arr[i];
arr[i] = currentMax;
if(currentMax < temp) {
currentMax = temp;
}
}
The solution ends up as For each index i, what is the maximum element seen so far.
Consider the following:
int currMax = -1;
int[] input = {1, 5, -3, 2, 8, 4, 7, 10, 3, 11, 2};
for (int i = 0; i < input.length; i++){
if (input[i] > currMax){ // if we find a new max element
currMax = input[i];
}
else if (input[i] < currMax){ // if value is less then max we replace it
input[i] = currMax;
}
}
System.out.println(Arrays.toString(input));
> [1, 5, 5, 5, 8, 8, 8, 10, 10, 11, 11]

finding min & max in an array with 3 increments

I need to find the max and min for every 3 elements of a data using java array.
For double data[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14} , what is the max and min in every 3 elements? In other words, what is the max and min for {1,2,3}, {4, 5, 6}, {7, 8, 9}, etc.
I have the following method, but it is not getting the right results.
for (int i = 0; i < data.length; i+=3) {
for (int r = i; r < i + 3 && r < data.length; r++) {
if (data[r] < lowest) { lowest = data[r]; }
if (data[r] > highest) { highest = data[r]; }
}
lowest = highest;
highest = 0;
How about this?
int[] data = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
int processed = 0;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < data.length; i++) {
if (data[i] < min) {
min = data[i];
}
if (data[i] > max) {
max = data[i];
}
processed++;
if (processed == 3) {
System.out.println("Min is: " + min);
System.out.println("Max is: " + max);
System.out.println("--------");
processed = 0;
min = Integer.MAX_VALUE;
max = Integer.MIN_VALUE;
}
}
Output:
Min is: 1
Max is: 3
--------
Min is: 4
Max is: 6
--------
Min is: 7
Max is: 9
--------
Min is: 10
Max is: 12
--------
It's unclear what to do with the numbers 13 and 14, as they don't form a block of 3, but I guess you get the idea of the algorithm.

Generate a random 2d array with random row length

I am trying to generate 2d random array similar to:
array[random][random2]
{
{1, 2},
{6, 4},
{-1, 5},
{-2}
}
the values in the array are also random, It may have -9 to -1 to 1 to 9 numbers.
Here's what i got:
public class gen2dArray {
public static void main(String args[]) {
Random random = new Random();
int n = 0;
int max = 5, min = 1;
n = random.nextInt(max - min + 1) + min;
int maxRowCol = (int)Math.pow(2,n);
int RandMaxRows = random.nextInt(maxRowCol);
int RandMaxColums = random.nextInt(maxRowCol);
int [][] array = new int [RandMaxRows][RandMaxColums];
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < random.nextInt(array[i].length)+1; j++) {
array[i][j] = random.nextInt(9) + 1;
}
}
System.out.println(Arrays.deepToString(array));
}
}
Output 1:
[
[4, 4, 5, 0],
[2, 3, 0, 0]
]
Output 2:
[
[5, 2, 1, 0, 0],
[3, 4, 2, 0, 0],
[3, 1, 5, 0, 0, 0],
[4, 3, 2, 0, 0]
]
There are few problems,
Some outputs are just [[]] or []
2.
Exception in thread "main" java.lang.IllegalArgumentException: n must be positive
at java.util.Random.nextInt(Random.java:300)
at gen2dArray.main(gen2dArray.java:23)
Getting the zeros in the array. There should be no zeros.
Output one has to be like:
[
[4, 4, 5],
[2, 3]
]
If you do not want to see the zeros, you should avoid making your arrays to big :
int [][] array = new int [RandMaxRows][];
// Code
array[value] = new int[random.nextInt(maxRowCol)];
This method should provide you an array of differents arrays of different sizes and just print out their real inputted values and not the 0 default values.
This is an example of an output :
[
[2, 4, 8, 7, 6, 6, 9],
[1, 3, 4, 2],
[1, 4, 4, 2, 7, 6, 8],
[9, 3, 6, 3, 7, 3],
[4, 5, 3, 2, 5, 2, 8]
]
Here is the modified code :
int [][] array = new int [random.nextInt(maxRowCol)][];
for (int i = 0; i < array.length; i++) {
array[i] = new int[random.nextInt(maxRowCol)];
for (int j = 0; j < array[i].length; j++) {
array[i][j] = random.nextInt(9) + 1;
}
}
When [] is printed, it means your Random did return 0.
A simple way to fix this is to add 1 to the concerned value and maybe decrease the MAX value from one also to keep the logic going.
Here is the code :
int maxRowCol = (int)Math.pow(2,n) - 1;
// Some code
int[][] array = new int [RandMaxRows + 1][];
You can simulate all these scenario by putting a System.out statement just before the array declaration.
System.out.println("RandMaxRows: " + RandMaxRows + "\tRandMaxColums: " + RandMaxColums);
Some outputs are just [[]] or []
This is happening when you are getting RandMaxRows as zero or both row and column are zero. We are using the Random.nextInt(n) for declaring the size of the array. The range of this method is 0 to n-1. So you can fix this by increment the outcome of the method.
n must be positive
This is happening when the RandMaxColums is zero. The input to the random.nextInt(n) must be greater then 0, it throws the exception.
Getting the zeros in the array. There should be no zeros.
The inner for-loop should be like this.
for (int j = 0; j < array[i].length; j++) {
You need iterate the array with it's length, for that any random number generation is not required. Use the current length and fill the array with randomly generated numbers.
Here is the work code for your problem:
public class gen2dArray {
public static void main(String args[]) {
Random random = new Random();
int n = 0;
int max = 5, min = 1;
n = random.nextInt(max - min + 1) + min;
int maxRowCol = (int)Math.pow(2,n);
int RandMaxRows = random.nextInt(maxRowCol);
int RandMaxColums = random.nextInt(maxRowCol);
System.out.println("RandMaxRows: " + RandMaxRows + "\tRandMaxColums: " + RandMaxColums);
int [][] array = new int [RandMaxRows+1][RandMaxColums+1];
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
int temp = random.nextInt(9);
array[i][j] = temp + 1;
}
}
System.out.println(Arrays.deepToString(array));
}
}
Sample Output:
RandMaxRows: 3 RandMaxColums: 3
[[1, 3, 3, 3], [2, 7, 6, 1], [5, 4, 4, 1], [6, 4, 6, 9]]

Categories

Resources