Homework: Sorting Algorithms - java

I am supposed to create an algorithm that sorts according to these steps:
Method 1
Select the lowest number in the list and swap with the first number.
Select the lowest number in the list and swap with the second number.
Start checking from the second number.
Select the lowest number in the list and swap with the third number.
Start checking from the third number.
Select the lowest number in the list and swap with the fourth number.
Start checking from the fourth number.
Repeat…until you reach the last number.
Currently, this is the code I have come up with:
public static void method1() {
int low = 999;
int index = 0;
int safe;
int[] num = new int[] { 33, 22, 8, 59, 14, 47, 60, 27 };
for(int i = 0; i < num.length; i++) {
if(low > num[i]) {
low = num[i];
index = i;
}
}
for (int i = 0; i < num.length; i++) {
safe = num[i];
num[i] = num[index];
low = 999;
for(int j = (i+1); j < num.length; j++) {
if(low > num[j]) {
low = num[j];
}
}
}
for (int i = 0; i < num.length; i++) {
System.out.print(num[i] +", ");
}
}
The output looks like this:
run:
8, 8, 8, 8, 8, 8, 8, 8,
BUILD SUCCESSFUL (total time: 0 seconds)
Why am I only getting values of 8 in the output? As this is homework, please don't tell me the answer. I would only like guidance, thanks!
EDIT:
Code now looks like this:
int low = 999;
int index = 0;
int safe;
int[] num = new int[] { 33, 22, 8, 59, 14, 47, 60, 27 };
for(int i = 0; i < num.length; i++) {
if(low > num[i]){
low = num[i];
index = i;
}
}
for (int i = 0; i < num.length; i++) {
safe = num[i];
num[i] = num[index];
low = 999;
for(int j = (i+1); j < num.length; j++) {
if(low > num[j]){
low = num[j];
index = j;
}
}
}
for (int i = 0; i < num.length; i++) {
System.out.print(num[i] +", ");
}
System.out.println("");
Which gives me an output of:
run:
8, 8, 8, 14, 14, 27, 27, 27,
BUILD SUCCESSFUL (total time: 0 seconds)

The date for this homework has been and gone, but thought I would add some step-by-step methodology.
The way I would approach this is to break it down into small steps. Each step should be a method or function.
1. The first step is to find the smallest number in the array, starting from N.
So the method for this would be:
private int findLowestStartingAtNth( int n ) {
int lowest = Integer.MAX_VALUE;
for( int i = n ; i < numbers.length ; i++ ) {
if( numbers[i] < lowest ) {
lowest = numbers[i];
}
}
return lowest;
}
2. Then we need to swap two arbitrary numbers in an array.
This is quite simple:
private void swapNumbers( int i, int j ) {
int temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
3. But if we want the output of findLowestStartingAtNth() to feed into the input of swapNumbers(), then we need to return the index not the number itself.
So the method from step 1. is altered to be:
private int findLowestStartingAtNth( int n ) {
int lowest = Integer.MAX_VALUE;
int index = n;
for( int i = n ; i < numbers.length ; i++ ) {
if( numbers[i] < lowest ) {
lowest = numbers[i];
index = i;
}
}
return index;
}
4. Let's use what we have to achieve step one
Select the lowest number in the list and swap with the first number.
The first number is the zero-th in the array.
int numbers = new int[] {33, 22, 8, 59, 14, 47, 60, 27};
int found = findLowestStartingAtNth( 0 );
swapNumbers(0, found);
5. We have a pattern. Start checking from 1st, swap with 1st. Start checking from 2nd, swap with 2nd. Start checking with X, swap with X.
So let's wrap this pattern in a further method:
private int[] numbers = new int[] {33, 22, 8, 59, 14, 47, 60, 27};
private void sort() {
for( int i = 0 ; i < numbers.length ; i++ ) {
int j = findLowestStartingAtNth( i );
swapNumbers(i, j);
}
}
6. Finally, wrap it in a class, and trigger it from main() method. See how clear the code is because it is broken into small steps.
The entire resulting class would be:
public class Method1 {
public static void main(String[] args) {
Method1 m = new Method1();
m.numbers = new int[] {33, 22, 8, 59, 14, 47, 60, 27};
m.sort();
System.out.println(Arrays.toString(m.numbers));
}
private int[] numbers;
private int findLowestStartingAtNth( int n ) {
int lowest = Integer.MAX_VALUE;
int index = n;
for( int i = n ; i < numbers.length ; i++ ) {
if( numbers[i] < lowest ) {
lowest = numbers[i];
index = i;
}
}
return index;
}
private void swapNumbers( int i, int j ) {
int temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
private void sort() {
for( int i = 0 ; i < numbers.length ; i++ ) {
int j = findLowestStartingAtNth( i );
swapNumbers(i, j);
}
}
}

Related

how to get minimum in 2d array java

I need help, please! I am building up the following code to extract the minimum value of each column of the distance
I have tried to compute the code but to no avail
public static void main(String[] args) {
int data[] = {2, 4, -10, 12, 3, 20, 30, 11};//,25,17,23}; // initial data
int noofclusters = 3;
int centroid[][] = new int[][]{
{0, 0, 0},
{2, 4, 30}
};
getCentroid(data, noofclusters, centroid);
}
public static int[][] getCentroid(int[] data, int noofclusters, int[][] centroid) {
int distance[][] = new int[noofclusters][data.length];
int cluster[] = new int[data.length];
int clusternodecount[] = new int[noofclusters];
centroid[0] = centroid[1];
centroid[1] = new int[]{0, 0, 0};
System.out.println("========== Starting to get new centroid =========");
for (int i = 0; i < noofclusters; i++) {
for (int j = 0; j < data.length; j++) {
//System.out.println(distance[i][j]+"("+i+","+j+")="+data[j]+"("+j+")-"+centroid[0][i]+"="+(data[j]-centroid[0][i]));
distance[i][j] = Math.abs(data[j] - centroid[0][i]);
System.out.print(distance[i][j] + " ,");
}
System.out.println();
}
int[] result = new int[distance.length];
for (int i = 0; i < distance.length; i++) {
//int min = distance;
int min = distance[i][0];
for (int j = 0; j < distance[0].length; j++) {
if (distance[i][j] < min) {
min = distance[i][j];
}
result[j] = min;
System.out.println(result[j] + ", ");
}
}
return result;
}
}
The result of the computation for distance gives
row 1: 0 ,2 ,12 ,10, 1 ,18 ,28 ,9
row 2: 2 ,0 ,14 ,8 , 1 ,16 ,26 ,7
row 3: 28,26,40 ,18, 27 ,10 ,0 ,19
I want to go through each column to get the minimum value
0 0 12 8 1 10 0 7
Thanks for your help in advance
To get the minimum value in each column, first, you need to iterate the column in the outer loop. By doing so, we can access the matrix colunm-wise.
Assign the first value of each column to a variable. Then iterate through the rows in the inner loop.
Check if the current value is less than the minimum value. If so, assign the smallest value to minimum.
When we use an array, we get an array of minimum values of the column.
To obtain the minimun value in each row, swap the loops and use min[i].
Below is an example code:
int []min = new int[column_lenght];
for(int j = 0; j < column_length; j++) {
min[j] = array[i][j];
for(int i = 0; i < row_length; i++) {
if(array[i][j] < min[j]) {
min[j] = array[i][j];
}
}
}
The min[] will contain the minimum value of each column.

Get the maximum summation of 2D array

There is a 2D array. int[][] arr= {{1,3,4,1},{5,7,8,9},{6,1,2,1}} . I want to get summation of each columns and get the maximum number. Finally it should be returned {5,7,8,9} . Because it has the maximum summation. I have mentioned i tried code below and it not return correct value. Help me to solve this
Your k is supposed to track the index with the greatest sum. So when you are resetting max you need to say k=i. You said i=k by mistake. Changing it makes your program run as desired.
EDIT: There was once code in the original question, to which this solution referred.
If the max column is expected, then I might have a solution:
import java.util.Arrays;
public class ArrayTest {
public static void main(String args[]) {
/*
* 1 3 4 1
* 5 7 8 9
* 6 1 2 1
*
*/
int[][] arr = {{1, 3, 4, 1}, {5, 7, 8, 9}, {6, 1, 2, 1}};
int m = arr.length;
int n = arr[0].length;
int[] arr2 = new int[n];
int p = 0;
int[][] colArray = new int[n][m];
for (int i = 0; i < n; i++) {
int[] arr_i = new int[m];
//System.out.println("i = " + i);
//System.out.println("p = " + p);
int sum = 0;
for (int j = 0; j < m; j++) {
arr_i[j] = arr[j][p];
sum += arr_i[j];
}
//System.out.println("Col: " + p + " : " + Arrays.toString(arr_i));
colArray[i] = arr_i;
arr2[p] = sum;
p++;
}
System.out.println("Sum: " + Arrays.toString(arr2));
int k = 0;
int max = arr2[0];
for (int i = 0; i < 3; i++) {
if (arr2[i] > max) {
max = arr2[i];
k = i;
}
}
System.out.println("Column index for max: " + k);
System.out.println("Column: " + Arrays.toString(colArray[k]));
}
}
Output:
Sum: [12, 11, 14, 11]
Column index for max: 2
Column: [4, 8, 2]
I recommend you find a way to break down your problem into smaller parts, solve each part with a function, then combine everything into a solution.
Example solution below:
public class Main {
public static long sum(int[] a){
long sum = 0;
for (int i : a) {
sum = sum + i;
}
return sum;
}
public static int[] withMaxSumOf(int[][] as){
// keep one sum for each array
long[] sums = new long[as.length];
// calculate sums
for (int i = 0; i < as.length; i++) {
int[] a = as[i];
sums[i] = sum(a);
}
// find the biggest one
int maxIndex = 0;
long maxSum = sums[0];
for (int i=1;i<sums.length;i++){
if (sums[i] > maxSum){
maxSum = sums[i];
maxIndex = i;
}
}
// return array that had biggest sum
return as[maxIndex];
}
public static void main(String[] args){
int[][] arr= {{1,3,4,1},{5,7,8,9},{6,1,2,1}};
// find the one with max sum
int[] max = withMaxSumOf(arr);
// print it
for (int i = 0; i < max.length; i++) {
int x = max[i];
if (i > 0) System.out.print(", ");
System.out.print(x);
}
System.out.println();
}
}
I think this might be your problem:
for(int i=0;i<3;i++) {
if(arr2[i]>max) {
max=arr2[i];
i=k;
}
}
I think that i=k really needs to be k=i.
Note also that it's worthwhile using better variable names. index instead of i, for instance. What is k? Call it "indexForHighestSum" or something like that. It doesn't have to be that long, but k is a meaningless name.
Also, you can combine the summation loop with the find-highest loop.
In the end, I might write it like this:
public class twoDMax {
public static void main(String args[]) {
int[][] arr= { {1,3,4,1}, {5,7,8,9}, {6,1,2,1} };
int indexForMaxRow = 0;
int previousMax = 0;
for(int index = 0; index < 4; ++index) {
int sum = 0;
for(int innerIndex = 0; innerIndex < 4; ++innerIndex) {
sum += arr[index][innerIndex];
}
if (sum > previousMax) {
previousMax = sum;
indexForMaxRow = index;
}
System.out.println(indexForMaxRow);
for(int index = 0; index < 4; ++index) {
System.out.println(arr[indexForMaxRow][index]);
}
}
}
I did a few other stylish things. I made use of more obvious variable names. And I am a little nicer about whitespace, which makes the code easier to read.
public static void main( String args[] ) {
int[][] arr = { { 1, 3, 4, 1 }, { 5, 7, 8, 9 }, { 6, 1, 2, 1 } };
int indexOfMaxSum = 0;
int maxSum = 0;
for ( int i = 0; i < arr.length; i++ ) {
int[] innerArr = arr[ i ]; // grab inner array
int sum = 0; // start sum at 0
for ( int j : innerArr ) {
// iterate over each int in array
sum += j; // add each int to sum
}
if ( sum > maxSum ) {
// if this sum is greater than the old max, store it
maxSum = sum;
indexOfMaxSum = i;
}
}
System.out.println( String.format( "Index %d has the highest sum with a sum of %d", indexOfMaxSum, maxSum ) );
int [] arrayWithLargestSum = arr[indexOfMaxSum]; // return me
}

Extracting a sequence from an array

I am writing code that reads an integer array in from a file, checks for an increasing sequence of numbers, and prints the length of the array as well as the sequence of numbers itself. The code I have written appears to correctly print the array, showing that is has found the array in the file, and count off the longest sequence of numbers, but it doesn't quite get the exact sequence right. Below is the code in its entirety and the output.
public static void main(String[] args) throws IOException {
File file = new File("input.txt");
Scanner s = null;
final int MAX_SIZE = 100;
int count = 0;
int[] tempArray = new int[MAX_SIZE];
try {
s = new Scanner(file);
int arrayAddress = 0;
System.out.println("File found!");
while (s.hasNextInt()) {
count++;
tempArray[arrayAddress] = s.nextInt();
arrayAddress++;
}
s.close();
}
catch (FileNotFoundException noFile) {
System.out.println("File not found.");
}
int[] inputArray = new int[count];
for (int i = 0; i < count; i++)
{
inputArray[i] = tempArray[i];
}
int sequence = 0;
int maxSequence = 0;
int sequenceEnd = 0;
for (int j = 0; j < count; j++) {
for (int k = j; k < count - 1; k++) {
if (inputArray[k + 1] == inputArray[k] + 1 ) {
sequence++;
sequenceEnd = k;
}
if (sequence > maxSequence) {
maxSequence = sequence;
sequence = 0;
}
}
}
int temp = 0;
System.out.println("The array is: " + Arrays.toString(inputArray));
System.out.println("The longest sequence of increasing numbers is " + maxSequence);
System.out.println("The sequence is as follows: ");
for (int i = sequenceEnd - maxSequence; i < sequenceEnd; i++) {
temp = inputArray[i];
System.out.println(temp);
}
}
The output for the code above on my sequence was as follows:
File found!
The array is: [7, 2, 13, 4, 5, 18, 11, 1, 20, 17, 15, 10, 19, 8, 16, 12, 6, 14, 9, 3]
The longest sequence of increasing numbers is 2
The sequence is as follows:
2
13
I really hope this isn't a minor oversight, but I can't seem to figure out where I have made an error. Thanks in advance if you have time to look over this and assist me.
There are two problems in your code:
(1) Finding the maximum length of the sequence
Your reset of the sequenc length
if (sequence > maxSequence) {
maxSequence = sequence;
sequence = 0;
}
should not be located within the inner loop. That is the one, where you are still counting the elements. You want to move it to the outer loop, i.e. from
for (int j = 0; j < count; j++) {
for (int k = j; k < count - 1; k++) {
//current location
}
}
for (int j = 0; j < count; j++) {
for (int k = j; k < count - 1; k++) {
}
//assumingly desired location
}
(2) Print sequence
The offset of your print-loop is off by one element and should be
for (int i = sequenceEnd - maxSequence1; i < sequenceEnd; i++) {
temp = inputArray[i-1];
System.out.println(temp);
}
Once maxSequence contains the correct amount of elements (i.e. not 2 as it is currently the case), it will print the entire sequence.

What is wrong with this Selection Sort Code?

I was asked to make a selection sort algorithm, but it's not working and I don't know why. Here's the code:
int count = 0;
int count2;
int min;
int size = scan.nextInt();
int temp = 0;
int[] numbers = new int[size];
while (count < size) {
numbers[count] = scan.nextInt();
count ++;
}
count = 0;
while (count < size) {
count2 = size;
min = numbers[count];
while (count < count2) {
count2 --;
if (numbers[count2] < numbers[min]) {
min = count2;
}
}
temp = numbers[temp];
numbers[temp] = numbers[count];
numbers[count] = temp;
count ++;
}
count = 0;
while (count < size) {
System.out.println(numbers[count]);
count ++;
}
}
Input:
10
1
0
2
9
3
8
4
7
5
6
Output:
1
2
9
8
3
3
8
4
7
4
In while loop you try to use numbers[0] element as the index of numbers[] numbers[min]
min = numbers[count]; \\min is value of first element of numbers[]
while (count < count2) {
count2 --;
if (numbers[count2] < numbers[min]) { \\ you try to use value of numbers[0] element as index of numbers[] aray.
min = count2;
}
replace if (numbers[count2] < numbers[min]) with if (numbers[count2] < min)
temp = numbers[temp];
numbers[temp] = numbers[count];
numbers[count] = temp;
count ++;
Take a second look at this code.
If you ran this where the first input was 11, it would error with index out of range.
In particular, what do you plan to accomplish with temp = numbers[temp]? You're assigning temp to essentially an arbitrary number, because numbers[0] could be anything.
The fact that you're getting duplicate values in your output (that aren't in your input) means that your swap doesn't work, thus:
temp = numbers[temp];
numbers[temp] = numbers[count];
numbers[count] = temp;
is wrong.
It should be min, not temp:
temp = numbers[min];
numbers[min] = numbers[count];
numbers[count] = temp;
Here is an algorithm that works and make use of a great functionality of for in java. To go through an array or a list you can do for (int current : array) This is far more convinient than using while or for like you do.
int min;
int mem = 0;
int size = 11;
int [] numbers = {10, 1, 0, 2, 9, 3, 8, 4, 7, 5, 6};
for (int i=0; i<size-1; i++){
min =i;
for(int j=i+1; j<size; j++){
if (numbers[j]<numbers[min]){
min = j;
}
}
// swap
mem= numbers[i];
numbers[i] = numbers[min];
numbers[min] = mem;
}
for (int toPrint : numbers){
System.out.println(toPrint);
}
}

How to copy non-duplicated values from one array to the other?

I am using first array to store all database of numbers where some numbers are duplicates.
I have went through this array to see which items are duplicated and am adding index of duplicated items to second array.
Now, I must loop through first array and add all but duplicated values to third array (assuming that we know which fields are duplicated).
But how to do this correctly? I can't make it stop adding every item from first array to third array.
Assuming I can't use HashSet().
The purpose of this is to demonstrate how to move one array to other with removed duplicated in O(N) time complexity.
Input numbers: 00, 11, 11, 22, 33, 44, 55, 55, 66, 77, 88, 99
Output which index are duplicated: 1, 2, 6, 7
Output I get: 00, 11, 11, 22, 33, 44, 55, 55, 66, 77, 88, 99 (same as the input)
Code:
public void dups()
{
int[] b = new int[100];
int[] c = new int[100];
int k = 0;
int n = 0;
int p = 0;
for (int i = 0; i < nElems; i++)
for (int j = 0; j < nElems; j++)
if(a[j].equals(a[i]) && j != i)
b[k++] = i;
for (int l = 0; l < k; l++)
System.out.print(b[l] + " ");
for (int m = 0; m < nElems; m++)
if (m != b[p + 2])
c[m] = (Integer) a[n++];
System.out.print("\n");
for (int o = 0; o < nElems; o++)
System.out.print(c[o] + " ");
}
It can be done in a simpler way:
Set<Integer> uniqueSet = new HashSet<Integer>();
uniqueSet.addAll(list);
//not uniqueSet contains only unique elements from the list.
The reason it works is that a Set cannot contain duplicates. So while adding elements to a Set, it ignores those that are duplicates.
You can use a HashSet instead of Array to store all database of numbers.
After that use Collections.toArray() to get your desired Array.
I see that the question got edited and we don't want to use HashSet anymore.
Anyways, your problem is already answered here, Algorithm: efficient way to remove duplicate integers from an array
Instead of marking all duplicates you could mark all that have already been seen earlier.
Instead of:
for (int i = 0; i < nElems; i++)
for (int j = 0; j < nElems; j++)
if(a[j].equals(a[i]) && j != i)
b[k++] = i;
Use something like:
for (int i = 0; i < nElems; i++)
for (int j = i+1; j < nElems; j++)
if(a[j].equals(a[i]))
b[k++] = j;
You should then see:
Output which index are duplicated: 2, 7
Which should be much easier to work with.
Here's a working solution - although I wouldn't do it this way:
public class Test {
Integer[] a = {00, 11, 11, 22, 33, 44, 55, 55, 66, 77, 88, 99};
int nElems = a.length;
public void dups() {
int[] b = new int[100];
int[] c = new int[100];
int k = 0;
int n = 0;
int p = 0;
for (int i = 0; i < nElems; i++) {
for (int j = i + 1; j < nElems; j++) {
if (a[j].equals(a[i])) {
b[k++] = j;
}
}
}
for (int l = 0; l < k; l++) {
System.out.print(b[l] + " ");
}
for (int m = 0; m < nElems; m++) {
if (m != b[p]) {
c[n++] = a[m];
} else {
p += 1;
}
}
System.out.print("\n");
for (int o = 0; o < nElems - k; o++) {
System.out.print(c[o] + " ");
}
}
public static void main(String args[]) {
new Test().dups();
}
}
which prints:
2 7
0 11 22 33 44 55 66 77 88 99
I don't know if this is what you were looking for. But it removes duplicate. Give it a shot,
int[] b = { 00, 11, 11, 22, 33, 44, 55, 55, 66, 77, 88, 99 };
List<Integer> noDups = new ArrayList<Integer>();
Boolean dupliceExists;
for (int i = 0; i < b.length; i++) {
dupliceExists = Boolean.FALSE;
for (Integer integ : noDups) {
if (Integer.valueOf(b[i]).equals(integ)) {
dupliceExists = Boolean.TRUE;
//Get index if you need the index of duplicate from here
}
}
if (!dupliceExists) {
noDups.add(b[i]);
}
}
for (int i = 0; i < noDups.size(); i++) {
System.out.println(noDups.get(i));
}
I am going to coding for copying non-duplicate elements from one Array to another Array.
/*
* print number of occurance of a number in an array beside it
*
* */
class SpoorNumberOfOccuranceInArray{
public static void main(String[] args){
int[] arr={65,30,30,65,65,70,70,70,80};
int[] tempArr=new int[arr.length];//making size compatible to source Array.
int count=0;
for(int i=0;i<arr.length;i++){
int temp=arr[i];
for(int j=0;j<tempArr.length;j++){
if(temp==tempArr[j]){ //Comparing the Availability of duplicate elements in the second Array.---------
break;
}
else{ //Inserting if value is not in the second Array.---------------
if( tempArr[j]==0){
tempArr[j]=temp;
break;
}//end if
}//end else
}//end if
}//end for
for(int i=0;i<tempArr.length;i++){
for(int j=0;j<arr.length;j++){
if(tempArr[i]==arr[j])
count++;
}
System.out.println(tempArr[i]+" "+count);
count=0;
}
}
}

Categories

Resources