Why my selection sort code doesn't work? - java

I have this function for selection sort:
public static void selectionSort(int[] n)
{
for(int start = 0; start < n.length; start++)
{
int smallest = start;
for(int i = start+1; i<n.length; i++)
{if(n[i]<n[start])
smallest = i;}
int tmp = n[start];
n[start] = n[smallest];
n[smallest] = tmp;
}
}
and i call it like this.
Random ran = new Random();
int n = 10;
int[] a = new int[n];
for(int i = 0; i<n; i++)
a[i] = ran.nextInt(1000);
However, it causes results like this..
640 900 610 168 650 610 527 356 802 486
486 640 356 168 610 527 610 650 802 900
the top one is not sorted the lower one is supposed to be sorted. However, it is not correct.

You are comparing the initial start index every singe iteration, even if you have found a smaller number you are still comparing it to the original start which should not happen. Once you find a smaller number you need to use that index for the comparison.
To compare it to the smallest number every iteration change (n[i]<n[start]) to (n[i]<n[smallest]) and that will fix your problem.
Hope this helps!

The second loop is useless because you are comparing, after all, just the first and the last item and smallest takes it's value from this comparison only.
By your code I guess you're trying to do a Bubble Sort, but the comparison and the index management is wrong, here is a posible solution:
public static void main(String[] args) {
Random ran = new Random();
int n = 10;
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = ran.nextInt(1000);
}
printArray(array);
selectionSort(array);
printArray(array);
}
private static void printArray(int[] array) {
System.out.print("Array: ");
for (int i : array) {
System.out.print(i + " ");
}
System.out.println();
}
private static void selectionSort(int[] array) {
for (int j = 0; j < array.length; j++) {
// Subtract 1 so you don't get a NullPointerException
// Subtract j so you don't compare the numbers already ordered
for (int i = 0; i < array.length - 1 - j; i++) {
if (array[i] > array[i + 1]) {
int tmp = array[i];
array[i] = array[i + 1];
array[i + 1] = tmp;
}
}
}
}
The algorithm is taken from the Spanish version (I'm from Argentina) of the link above, which is also in the English version with other notation.
Hope this helps. Best regards

Try to use this version of code it's functional:
public static void main(String[] args) {
Random ran = new Random();
int n = 10;
int[] a = new int[n];
for (int i = 0; i < n; i++)
a[i] = ran.nextInt(1000);
selectionSort(a);
for (int i : a) {
System.out.print(i+" ");
}
}
public static void selectionSort(int[] n)
{
for(int start = 0; start < n.length-1; start++)
{
int smallest = start;
for(int i = start+1; i<n.length; i++)
{if(n[i]<n[smallest])
smallest = i;}
int tmp = n[start];
n[start] = n[smallest];
n[smallest] = tmp;
}
}

Related

trouble implementing counting sort for strings

I get this error when I attempt to sort it based off the second char in the string but it runs
fine when I use the first char
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 8
at StringCountSort.countingSort(StringCountSort.java:27)
at StringCountSort.main(StringCountSort.java:38)
import java.util.Arrays;
public class StringCountSort{
public static void countingSort(String[] array, int size, int digit)
{
String[] result = new String[size+1];
int maximum = 122;
int[] count = new int[maximum + 1];
for (int i = 0; i < count.length; i++){
count[i] = 0;
}
for (int i = 0; i < size; i++){
count[array[i].charAt(digit)] +=1;
}
for (int i = 1; i < count.length; i++){
count[i] += count[i-1];
}
for (int i = size -1; i >= 0; i--){
result[count[array[i].charAt(digit)] - 1] = array[i];
count[array[i].charAt(0)]--;
}
for (int i = 0; i < size; i++) {
array[i] = result[i];
}
}
public static void main(String args[]){
String[] data = { "eg", "fa", "bz", "ch", "hv", "df", "ag" };
StringCountSort.countingSort(data, data.length, 1);
System.out.println("Sorted Array in Ascending Order: ");
System.out.println(Arrays.toString(data));
}
}
line 28 result[count[array[i].charAt(digit)] - 1] = array[i];
line 37 StringCountSort.countingSort(data, data.length, 1);
Change
count[array[i].charAt(0)]--;
to
count[array[i].charAt(digit)]--;
This should do the trick.
I also suggest the following improvements:
You don't need to pass the length of array as an argument.
You don't need to set every int of count to 0;
maximum should be Character.MAX_VALUE, to support every possible character.
The finished function could look like this:
public static void countingSort(String[] array, int digit) {
String[] result = new String[array.length];
int[] count = new int[Character.MAX_VALUE + 1];
for (int i = 0; i < array.length; i++){
count[array[i].charAt(digit)]++;
}
for (int i = 1; i < count.length; i++){
count[i] += count[i-1];
}
for (int i = array.length -1; i >= 0; i--){
result[count[array[i].charAt(digit)] - 1] = array[i];
count[array[i].charAt(digit)]--;
}
for (int i = 0; i < array.length; i++) {
array[i] = result[i];
}
}
Things that need to be changed are (if you want to sort the strings on the basis of first character)
count[array[i].charAt(digit)] +=1 to count[array[i].charAt(0)] +=1
result[count[array[i].charAt(digit)] - 1] = array[i]; count[array[i].charAt(0)]--; to result[--count[array[i].charAt(0)]] = array[i];
If you want to sort the string on the basis of the second character then simply change :
count[array[i].charAt(0)]--; to count[array[i].charAt(digit)]--;

Random generator Error

I want to write a program that is randomizing 1000000 times and finally chooses the number from 1 - 45 that was randomly generated most of the times. The code I have written is this:
public class Randomizer {
public static int[][] numbers = new int[45][2];
public static int maxN = 0;
public static int finalChoice;
public static void main(String[] args){
for(int i = 0; i < 45; i++){
numbers[i][0] = i + 1;
numbers[i][1] = 0;
}
for(int i = 0; i < 1000000; i ++){
int rnd = (int)(Math.random() * 45 + 1);
for(int j = 0; j < 45; j++){
if(rnd == numbers [j] [0]){
numbers[j][1] ++ ;
break;
}
}
}
for(int i = 0; i < 45; i++){
if(maxN < numbers[i][1]){
finalChoice = numbers[i][0];
}
System.out.print(numbers[i][1]+" \t");
}
System.out.println("\nFinal Choice: "+finalChoice);
}
}
The problem is that it keeps printing 45. Where could the error be?
Your loop that generates the numbers and populates the array looks fine. The only problem is in the final loop, which searches for the highest occurring number.
You forgot to update maxN, so each iteration updates finalChoice (since maxN < numbers[i][1] is always true, assuming that each number from 1 to 45 was randomly chosen at least once) and it ends up being 45.
Fix :
for(int i = 0; i < 45; i++){
if(maxN < numbers[i][1]){
finalChoice = numbers[i][0];
maxN = numbers[i][1]; // add this
}
System.out.print(numbers[i][1]+" \t");
}
Try this:
Random r = new Random();
for (int i = 0; i <= 1000000; i++) {
int Low = 1;
int High = 45;
int R = r.nextInt(High - Low) + Low;
}

How can I split a integer array to n integer array dynamically?

Here I have integer array contains 81 values so that I need to store 9 values per array total I need to get 9 arrays. Eg: array1 from 1 to 9 and array2 from 10 to 18 and array3 from 19 to 27 like that. Can anybody help me how to get this values?
public class demo {
public static void main(String[] args) {
int num = 81;
int numArray = num / 9;
int[] input = new int[num];
for (int i = 0; i < num; i++) {
input[i] = i + 1;
}
for (int j = 0; j < input.length; j++) {
System.out.println(input[j]);
}
}
}
How to get desired result?
You can use System#arraycopy():
int[] first_part = new int[27];
int[] second_part = new int[27];
int[] third_part = new int[27];
System.arraycopy(input, 0, first_part, 0, 27);
System.arraycopy(input, 27, second_part, 0, 27);
...
I've just noticed that you want 9 parts, you can easily put this in a loop and use arraycopy.
public static void main(String[] args) {
int num = 85;
int limit = 5;
int index = 0;
int extra = 0;
int finalArrayIndex = 0;
int[] innerArray = null;
int[] input = new int[num];
boolean isEnd = false;
if (num % limit > 0) {
extra = 1;
}
int[][] finalArray = new int[(num / limit) + extra][limit];
for (int i = 0; i < input.length; i = i + (limit)) {
innerArray = new int[limit];
for (int j = 0; j < limit; j++) {
innerArray[j] = input[index++];
if (index >= input.length) {
isEnd = true;
break;
}
}
finalArray[finalArrayIndex++] = innerArray;
if (isEnd) {
break;
}
}
// just for test
for (int k = 0; k < finalArray.length; k++) {
for (int l = 0; l < finalArray[k].length; l++) {
System.out.println("finalArray[" + k + "]" + "[" + l + "] : "
+ finalArray[k][l]);
}
}
}
This is dynamic solution, you can change value of num and limit variables. I hope this will help you :)
Java Fiddle link : http://ideone.com/jI8IOb
My suggestion is use subList
You can follow these steps.
Store all 81 values in a List (ArrayList)
Then create 9 sub List from that using subList()
You can convert List to array.
List<Integer> fullList=new ArrayList<>();
List<Integer> list1=fullList.subList(0,8); // first 9 elements
Integer[] bar = list1.toArray(new Integer[list1.size()]);

Improve performance of reversing array

I am trying to solve question at Reverse Game
When I submit my code, in some of the testcases it is getting timeout.
I think problem may be in reverseSubArray() method but I am not sure how to improve performance here.
Following is my code:
public class ReverseGame
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
int testCases = Integer.parseInt(scanner.nextLine());
int[] numberOFBalls = new int[testCases];
int[] ballNumberArray = new int[testCases];
for (int i = 0; i < testCases; i++)
{
numberOFBalls[i] = scanner.nextInt();
ballNumberArray[i] = scanner.nextInt();
}
for (int i = 0; i < testCases; i++)
{
process(numberOFBalls[i], ballNumberArray[i]);
}
scanner.close();
}
private static void process(int totalNumberOFBalls, int ballNumber)
{
int[] ballsArray = new int[totalNumberOFBalls];
int maximumNumberOnBall = totalNumberOFBalls - 1; // This is because
// balls are numbered
// from 0.
// As the first step is to reverse the Balls arrangement, So insert into
// ballsArray in descending order of index.
for (int i = 0; i < totalNumberOFBalls; i++)
ballsArray[i] = maximumNumberOnBall--;
for (int i = 1; i < totalNumberOFBalls; i++)
{
ballsArray = reverseSubArray(ballsArray, i);
}
int position = findPosition(ballsArray, ballNumber);
System.out.println(position);
}
private static int[] reverseSubArray(int[] a, int fromIndex)
{
int temp = 0, counter = 1;
int midIndex = (a.length - fromIndex) / 2;
for (int i = fromIndex; i < fromIndex + midIndex; i++)
{
temp = a[a.length - (counter)];
a[a.length - (counter)] = a[i];
a[i] = temp;
counter++;
}
/*
* System.out.println(); for (int i = 0; i < a.length; i++)
* System.out.print(a[i] + " ");
*/
return a;
}
private static int findPosition(int[] ballsArray, int ballNumber)
{
for (int i = 0; i < ballsArray.length; i++)
{
if (ballsArray[i] == ballNumber)
return i;
}
return 0;
}
}
The time complexity of your solution is O(n ^ 2). It is too slow for n = 10 ^ 5. So you need to use a better algorithm. Here is simple linear solution which uses the fact that we do not need to know the positions of all balls(we need only the k-th):
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
PrintWriter out = new PrintWriter(System.out);
int testsCount = in.nextInt();
for (int t = 0; t < testsCount; t++) {
int n = in.nextInt();
int k = in.nextInt();
// Simulates all rotations,
// but keeps track only of the k-th ball.
// It does not matter what happens to the others.
for (int i = 0; i < n; i++)
if (k >= i)
k = i + n - 1 - k;
out.println(k);
}
out.flush();
}
}
This solution has an O(n) time complexity and easily passes all test cases.
It is actually possible to find the positions of all balls in linear time, but it is not required here.

Stuck with while loop. In processing

I have an array of 100 numbers and I only gave the array even values. How can I print out how many elements of the array I have to add to obtain a sum < than 1768 using a WHILE LOOP? The following is what I have so far and I am stuck... thanks in advance for the help
void setup() {
int[] x = new int[100];
int i=0;
int sum=0;
for(i=0; i<100; i++) {
if (i%2==0) {
x[i]=i;
sum+=x[i];
}
}
}
void setup() {
int i = 0;
int sum = 0;
int counter = 0;
while (sum < 1768) {
sum += i;
i += 2;
counter++;
}
System.out.println(counter);
}
You start with the even index of 0. Then just skip odd numbers by using i += 2.
If the number of elements is limited with 100, add i < 200 to the while condition:
while (sum < 1768 && i < 200)
The array of 100 even numbers will contain numbers from 0 to 200.
The variable counter will contain the number of additions performed. Its value will be equal to i / 2, so you can remove that additional variable.
You can use this loop and element number would be i+1.
for(int i=0,k=0; k<1768; i++,k+=x[i]) {
System.out.println(x[i]+" - "+k);
}
While loop -
int i=0,k=0;
while(k<1768; ) {
System.out.println(x[i]+" - "+k);
i++,k+=x[i];
}
You are skipping indexes in your array.You are only filling every other 'slot'
Also, it would probably be easier to use a while loop to check against your max value (1728)
int[] x = new int[100];
int i = 0;
int sum = 0;
int max = 1728;
while (sum < max && i < 100)
{
x[i] = i*2;
if ((x[i] + sum) < max)
{
sum += x[i];
}
i++;
}
void setup() {
int[] x = new int[100];
int maxValue = 1768;
int i;
int sum=0;
while(sum<maxValue) {
if (i%2==0) {
x[i]=i;
sum+=x[i];
i++;
}
}
System.out.println(i+" Elements needed")
}
following is code:
void setup() {
int[] x = new int[100];
int i=0;
int sum=0;
for(i=0; i<100; i++) {
if (i%2==0) {
sum += i;
if(sum<1768){
num +=1;
}
}
}
}

Categories