Sort 2D array in ascending order - java

class arrayDemo {
static void sort2D(int[][] B) {
boolean swap = true;
int oy=0;
int temp=0;
for(int ox=0;ox<B.length;ox++){
while(oy<B[ox].length) {
while(swap) {
swap = false;
for(int ix=0;ix<B.length;ix++) {
for(int iy=0;iy<B[ix].length;iy++) {
if(B[ox][oy]<B[ix][iy]) {
temp = B[ix][iy];
B[ix][iy] = B[ox][oy];
B[ox][oy] = temp;
swap = true;
}
}
}
}
oy++;
}
}
for(int row=0;row<B.length;row++)
for(int col=0;col<B[row].length;col++)
System.out.println(B[row][col]);
}
public static void main(String...S) {
int y[][] = {{10,20,0,30},{10,5,8},{3,9,8,7},{2,3}};
sort2D(y);
}
}
I am trying to sort a 2D array in ascending order.
Input: {{10,20,0,30},{10,5,8},{3,9,8,7},{2,3}};
Output: 30,20,10,10,9,8,8,7,5,3,0,2,3
Can someone help me know what is wrong with my code.

You are comparing elements that are not in the same row or column. Each sub-array should be sorted individually. You might want to reconsider this line if (B[ox][oy] < B[ix][iy]).

That code has a number of problems.
It throws ArrayIndexOutOfBoundsException. This is because all for loop tests test against B.length, which is not correct for inner arrays.
You are comparing every pair of elements, but some pairs are the reverse of other pairs, and the reverse pairs should not be tested. You need to limit the scope of your inner set of for loops, by starting at a different index.
To fix all these problems, the path of least resistance is to dump the 2D array into a 1D array and sort that, which is much easier.
Here is code that has been tested and shown to work:
static void sort2D(int[][] B) {
int count = 0;
for (int[] is : B)
for (int i : is)
count++;
int[] A = new int[count];
count = 0;
for (int[] is : B)
for (int i : is)
A[count++] = i;
int temp;
for (int i = 0; i < A.length; i++)
for (int j = i + 1; j < A.length; j++)
if (A[i] > A[j]) {
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
for (int i = 0; i < A.length; i++)
System.out.print(A[i] + ",");
}

Related

Why is my selection sort algorithm not working?

I'm trying to make a selection sort algorithm in java that finds the smallest element of an unsorted array and puts it on the end of a new array. But my program only copies the first element twice, gets the next one, and then the rest is all zeroes:
public static int find_min(int[] a){
int m = a[0];
for (int i = 0; i < a.length; i++){
if (m > a[i])
m = a[i];
}
return m;
}
public static int[] selectionSort(int[] unsorted){
int[] c = new int[unsorted.length];
for(int i = 0; i < unsorted.length; i++){
int smallest = find_min(unsorted);
c[i] = smallest;
unsorted = Arrays.copyOfRange(unsorted, i+1, unsorted.length );
}
return c;
}
When I put in something like:
public static void main(String[] args){
int a[] = {1,-24,4,-4,6,3};
System.out.println(Arrays.toString(selectionSort(a)));
}
I get:
[-24, -24, -4, 0, 0, 0]
where is this going wrong? Is this a bad algorithm?
Ok, let's revisit the selection sort algorithm.
public static void selectionSort(int[] a) {
final int n = a.length; // to save some typing.
for (int i = 0; i < n - 1; i++) {
// i is the position where the next smallest element should go.
// Everything before i is sorted, and smaller than any element in a[i:n).
// Now you find the smallest element in subarray a[i:n).
// Actually, you need the index
// of that element, because you will swap it with a[i] later.
// Otherwise we lose a[i], which is bad.
int m = i;
for (int j = m + 1; j < n; j++) {
if (a[j] < a[m]) m = j;
}
if (m != i) {
// Only swap if a[i] is not already the smallest.
int t = a[i];
a[i] = a[m];
a[m] = t;
}
}
}
In conclusion
You don't need extra space to do selection sort
Swap elements, otherwise you lose them
Remembering the loop invariant is helpful

why wont main recieve my returned int value java

so when I go to compile this Eclipse says, that the numbers for Insertionct and Shakerct are 0 and prints out a tie. I know for a fact that both methods are sorting correctly, but for some reason it doesn't return the amount of comparisons that they are making to main in order to decide which one sorted the array faster. Thanks for any help in advance.
import java.io.*;
import java.util.*;
public class Sorts {
private static Scanner in;
public static void main(String[] args) throws Exception {
in = new Scanner(System.in);
System.out.print("How many strings will you be entering? ");
int sz = Integer.parseInt (in.nextLine());
String[] A = new String[sz];
String[] B = new String[sz];
for (int i = 0; i < sz; i++){
System.out.print ("Enter String #"+(i+1)+": ");
A[i] = in.nextLine();// sets the array at i equal to a string
B[i] = A[i]; // sets array B to the same as array A so I can use it in the shaker sort method
}
int Insertionct = 0;
int Shakerct = 0;
System.out.println(Insertionct);
System.out.println(Shakerct);
if (Shakerct > Insertionct) {
System.out.println("Insertion Sort was faster!");
} else if (Shakerct < Insertionct) {
System.out.println("Shaker Sort was faster!");
} else {
System.out.println("It was a tie");
}
}
public static int InsertionSort (int Insertionct, String[] A) throws Exception { //sorts the array of strings with the insertion sort.
// initializes the count variable
int sz = A.length; // sets size equal toe array A
for (int i = 0; i < sz-1; i++)
for (int j = i; j >= 0 && A[j].compareTo (A[j+1]) > 0; j--) {
Insertionct++;
String t = A[j]; //switch A[j], A[j+1]
A[j] = A[j+1];
A[j+1] = t;
}
return Insertionct;
}
public static int ShakerSort (int Shakerct, String[] B) throws Exception {//Uses the ShakerSort in order to order the array.
int sz = B.length;
for (int i = 0; i < sz; i++){
int nsct = 0;
for(int j = nsct+sz-1; j > i; j--){//runs through the array backwards and then swaps if it needs to
Shakerct++;
if (B[j].compareTo(B[j-1]) < 0) {
nsct = 0;
String t = B[j];
B[j] = B[j-1];
B[j-1] = t;
} else {
nsct++; // if no swap happens it increases no swap to increment the starting points.
}
}
for (int j = nsct; j > sz-i-1; j++){
if (B[j].compareTo(B[j+1]) > 0){//runs through the array going forward swaps if needed
Shakerct++;
nsct = 0;
String t = B[j];
B[j] = B[j+1];
B[j+1] = t;
} else {
nsct++;// increases no-swap count if no swap happens and changes the starting point.
}
}
}
return Shakerct;
}
}
You don't call InsertionSort and ShakerSort in main.

How do you Bubble Sort Largest to Smallest

Sorry am kind of lame at this. I've looked on here for a way to Bubble sort so that I can get an array to go from largest number to smallest. I've found some error in my current iteration of the sort, I can't seem to get the array to sort once it compares a smaller number to a bigger number. Here what I am using thus far.
//bubble sort
for(int i=0;i<size;i++)
{
for(int v=1;i<(size-i);i++)
{
if(arrInt[v-1]<arrInt[v])
{
temp = arrInt[v-1];
arrInt[v-1]=arrInt[v];
arrInt[v]=temp;
}
}
}
int n = arrInt.length;
int temp = 0;
for (int i = 0; i < n; i++) {
for (int v = 1; v < (n - i); v++) {
if (arrInt[v - 1] < arrInt[v]) {
temp = arrInt[v - 1];
arrInt[v - 1] = arrInt[v];
arrInt[v] = temp;
}
}
}
Try this.
Update - Replaced j with v
The problem is the inner loop should be from 1 to n. Instead your inner loop stops early.
Also you are testing i in the inner loop condition, but you should be testing v.
Try this:
//bubble sort
for(int i=0;i<size;i++)
{
for(int v=1;v<size;v++)
{
if(arrInt[v-1]<arrInt[v])
{
temp = arrInt[v-1];
arrInt[v-1]=arrInt[v];
arrInt[v]=temp;
}
}
}
Bubble Sort Method for Descending Order
public static void BubbleSort( int[ ] arr){
int records=arr.length-1;
boolean notSorted= true; // first pass
while (notSorted) {
notSorted= false; //set flag to false awaiting a possible swap
for( int count=0; count < records; count++ ) {
if ( arr[count] < arr[count+1] ) { // change to > for ascending sort
arr[count]=arr[count]+arr[count+1];
arr[count+1]=arr[count]-arr[count+1];
arr[count]=arr[count]-arr[count+1];
notSorted= true; //Need to further check
}
}
}
}
In this method when array is sorted then it does not check further.
Usually I implement Bubble sort like this,
for(int i=0;i<size-1;i++) {
for(int v=0;v<(size-1-i);v++){
if(arrInt[v]<arrInt[v+1])
{
temp = arrInt[v];
arrInt[v]=arrInt[v+1];
arrInt[v+1]=temp;
}
}
}
You know what is the problem is, in your code??? Look at the inner loop, you are initializing v but checking and changing i. Must be a copy paste error.. :P
Hope it helped...
Here you go:
int x = 0;
for(int i = 0; i < array.length; i++)
for(int j = 0; j < array.length; j++)
if(array[i] > array[j + 1])
x = array[j + 1];
array[j + 1]= array[i];
array[i] = x;
x here is a temporary variable you only need for this operation.
here's a complete running program for you. Hope that keeps you motivated
package test;
public class BubbleSort {
private static int[] arr = new int[] { 1, 45, 65, 89, -98, 2, 75 };
public static void sortBubbleWay() {
int size = arr.length-1;
int temp = 0; // helps while swapping
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i; j++) {
if (arr[j] < arr[j+1]) { /* For decreasing order use < */
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
private static void showShortedArray() {
for (int elt : arr) {
System.out.println(elt);
}
}
public static void main(String args[]) {
sortBubbleWay();
showShortedArray();
}
}//end of class

Selection Sort in Java, ways I can improve the code?

This is the code I have for my selection sort program, I want to know if there's any way of improving the code without using additional methods or classes.
public class Selection_Sort {
public static void main(String[] args) {
int arr[]={234,151,123,4,5342,76,48};
int min=0; int temp;
for(int i=0;i<=arr.length-1;i++){
min=i;
for (int k=i+1;k<arr.length;k++){
if(arr[k]<arr[i]){
temp=arr[i];
arr[i]=arr[k];
arr[k]=temp;
}
}
}
for (int j=0;j<=arr.length-1;j++)
System.out.println(arr[j]+" ");
}
}
public static void main(String[] args) {
int arr[]={234,151,123,4,5342,76,48};
int arrLength = arr.length;
for(int i=0;i<arrLength-1;i++){
int min=i;
for (int k=i+1;k<arrLength;k++){
if(arr[k]<arr[min]){
min = k;
}
}
if (i != min) {
int temp=arr[i];
arr[i]=arr[min];
arr[min]=temp;
}
}
for (int j=0;j<arrLength;j++) {
System.out.println(arr[j]+" ");
}
}
Looks like you are using the bubblesort algorithm which is very slow. If you want to improve your code, i would recommend to use an algorithm like ripplesort or quicksort.
Slight improvement should be like this :
int arrayLength = arr.length;
// Then use it in conditional statement of for loop.
So that it won't invoke length property of Array every time in loop. For small number of loops it doesn't impact much but it will help to reduce the time when loops are more or number of iteration of loop are more.
The value of the local variable min is not used
k <= arr.length-1
-->
k < arr.length
Use this
class Selection {
public static void main(String[] args) {
int arr[]={234,151,123,4,5342,76,48}; /* arr[0] to arr[n-1] is the array to sort */
int lowest, i, j;
for(i = 0 ; i < arr.length-1; i++) { /* advance the position through the entire array */
lowest = i; /* assume the min is the first element */
for(j = i+1 ; j < arr.length; j++) { /* if this element is less, then it is the new minimum */
if(arr[j] < arr[lowest]) {
lowest = j; /* found new minimum; remember its index */
}
}
if(lowest != i) { /* lowest is the index of the minimum element. Swap it with the current position */
int temp = arr[i];
arr[i] = arr[lowest];
arr[lowest] = temp;
}
}
for (int k = 0; k <= arr.length-1 ; k++) {
System.out.println(arr[k] + " ");
}
}
}
This is the selection sort algorithm you asked.
Here is original Selection sort implementation. The implementation in question in not using min to perform the swap operation.
public static void sort(int[] arr) {
int min=-1;
for (int i = 0; i < arr.length; i++) {
min = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[min] > arr[j]) {
min = j;
}
}
if (min != i) {
int temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
}
public class JavaApplication55 {
public static void main(String[] args) {
int[] array ={234,435,567,768,123,456,789,789,5670,6789};
for(int j =0;j< array.length;j++){
for(int i =j+1;i < array.length;i++ ){
int temp;
if(array[j]>array[i]){
temp =array[j];
array[j] =array[i];
array[i] =temp;
}
else{}
}}
for(int k =0;k< array.length;k++){
System.out.println(array[k]);
}
}
enter code here
}

How can I find the smallest covering prefix of an array in Java?

Find the first covering prefix of a given array.
A non-empty zero-indexed array A consisting of N integers is given. The first covering
prefix of array A is the smallest integer P such that and such that every value that
occurs in array A also occurs in sequence.
For example, the first covering prefix of array A with
A[0]=2, A[1]=2, A[2]=1, A[3]=0, A[4]=1 is 3, because sequence A[0],
A[1], A[2], A[3] equal to 2, 2, 1, 0 contains all values that occur in
array A.
My solution is
int ps ( int[] A )
{
int largestvalue=0;
int index=0;
for(each element in Array){
if(A[i]>largestvalue)
{
largestvalue=A[i];
index=i;
}
}
for(each element in Array)
{
if(A[i]==index)
index=i;
}
return index;
}
But this only works for this input, this is not a generalized solution.
Got 100% with the below.
public int ps (int[] a)
{
var length = a.Length;
var temp = new HashSet<int>();
var result = 0;
for (int i=0; i<length; i++)
{
if (!temp.Contains(a[i]))
{
temp.Add(a[i]);
result = i;
}
}
return result;
}
I would do this
int coveringPrefixIndex(final int[] arr) {
Map<Integer,Integer> indexes = new HashMap<Integer,Integer>();
// start from the back
for(int i = arr.length - 1; i >= 0; i--) {
indexes.put(arr[i],i);
}
// now find the highest value in the map
int highestIndex = 0;
for(Integer i : indexes.values()) {
if(highestIndex < i.intValue()) highestIndex = i.intValue();
}
return highestIndex;
}
Your question is from Alpha 2010 Start Challenge of Codility platform. And here is my solution which got score of 100. The idea is simple, I track an array of counters for the input array. Traversing the input array backwards, decrement the respective counter, if that counter becomes zero it means we have found the first covering prefix.
public static int solution(int[] A) {
int size = A.length;
int[] counters = new int[size];
for (int a : A)
counters[a]++;
for (int i = size - 1; i >= 0; i--) {
if (--counters[A[i]] == 0)
return i;
}
return 0;
}
here's my solution in C#:
public static int CoveringPrefix(int[] Array1)
{
// Step 1. Get length of Array1
int Array1Length = 0;
foreach (int i in Array1) Array1Length++;
// Step 2. Create a second array with the highest value of the first array as its length
int highestNum = 0;
for (int i = 0; i < Array1Length; i++)
{
if (Array1[i] > highestNum) highestNum = Array1[i];
}
highestNum++; // Make array compatible for our operation
int[] Array2 = new int[highestNum];
for (int i = 0; i < highestNum; i++) Array2[i] = 0; // Fill values with zeros
// Step 3. Final operation will determine unique values in Array1 and return the index of the highest unique value
int highestIndex = 0;
for (int i = 0; i < Array1Length; i++)
{
if (Array2[Array1[i]] < 1)
{
Array2[Array1[i]]++;
highestIndex = i;
}
}
return highestIndex;
}
100p
public static int ps(int[] a) {
Set<Integer> temp = new HashSet<Integer>();
int p = 0;
for (int i = 0; i < a.length; i++) {
if (temp.add(a[i])) {
p = i+1;
}
}
return p;
}
You can try this solution as well
import java.util.HashSet;
import java.util.Set;
class Solution {
public int ps ( int[] A ) {
Set set = new HashSet();
int index =-1;
for(int i=0;i<A.length;i++){
if(set.contains(A[i])){
if(index==-1)
index = i;
}else{
index = i;
set.add(A[i]);
}
}
return index;
}
}
Without using any Collection:
search the index of the first occurrence of each element,
the prefix is the maximum of that index. Do it backwards to finish early:
private static int prefix(int[] array) {
int max = -1;
int i = array.length - 1;
while (i > max) {
for (int j = 0; j <= i; j++) { // include i
if (array[i] == array[j]) {
if (j > max) {
max = j;
}
break;
}
}
i--;
}
return max;
}
// TEST
private static void test(int... array) {
int prefix = prefix(array);
int[] segment = Arrays.copyOf(array, prefix+1);
System.out.printf("%s = %d = %s%n", Arrays.toString(array), prefix, Arrays.toString(segment));
}
public static void main(String[] args) {
test(2, 2, 1, 0, 1);
test(2, 2, 1, 0, 4);
test(2, 0, 1, 0, 1, 2);
test(1, 1, 1);
test(1, 2, 3);
test(4);
test(); // empty array
}
This is what I tried first. I got 24%
public int ps ( int[] A ) {
int n = A.length, i = 0, r = 0,j = 0;
for (i=0;i<n;i++) {
for (j=0;j<n;j++) {
if ((long) A[i] == (long) A[j]) {
r += 1;
}
if (r == n) return i;
}
}
return -1;
}
//method must be public for codility to access
public int solution(int A[]){
Set<Integer> set = new HashSet<Integer>(A.length);
int index= A[0];
for (int i = 0; i < A.length; i++) {
if( set.contains(A[i])) continue;
index = i;
set.add(A[i]);
}
return index;
}
this got 100%, however detected time was O(N * log N) due to the HashSet.
your solutions without hashsets i don't really follow...
shortest code possible in java:
public static int solution(int A[]){
Set<Integer> set = new HashSet<Integer>(A.length);//avoid resizing
int index= -1; //value does not matter;
for (int i = 0; i < A.length; i++)
if( !set.contains(A[i])) set.add(A[index = i]); //assignment + eval
return index;
}
I got 100% with this one:
public int solution (int A[]){
int index = -1;
boolean found[] = new boolean[A.length];
for (int i = 0; i < A.length; i++)
if (!found [A[i]] ){
index = i;
found [A[i]] = true;
}
return index;
}
I used a boolean array which keeps track of the read elements.
This is what I did in Java to achieve 100% correctness and 81% performance, using a list to store and compare the values with.
It wasn't quick enough to pass random_n_log_100000 random_n_10000 or random_n_100000 tests, but it is a correct answer.
public int solution(int[] A) {
int N = A.length;
ArrayList<Integer> temp = new ArrayList<Integer>();
for(int i=0; i<N; i++){
if(!temp.contains(A[i])){
temp.add(A[i]);
}
}
for(int j=0; j<N; j++){
if(temp.contains(A[j])){
temp.remove((Object)A[j]);
}
if(temp.isEmpty()){
return j;
}
}
return -1;
}
Correctness and Performance: 100%:
import java.util.HashMap;
class Solution {
public int solution(int[] inputArray)
{
int covering;
int[] A = inputArray;
int N = A.length;
HashMap<Integer, Integer> map = new HashMap<>();
covering = 0;
for (int i = 0; i < N; i++)
{
if (map.get(A[i]) == null)
{
map.put(A[i], A[i]);
covering = i;
}
}
return covering;
}
}
Here is my Objective-C Solution to PrefixSet from Codility. 100% correctness and performance.
What can be changed to make it even more efficient? (without out using c code).
HOW IT WORKS:
Everytime I come across a number in the array I check to see if I have added it to the dictionary yet.
If it is in the dictionary then I know it is not a new number so not important in relation to the problem. If it is a new number that we haven't come across already, then I need to update the indexOftheLastPrefix to this array position and add it to the dictionary as a key.
It only used one for loop so takes just one pass. Objective-c code is quiet heavy so would like to hear of any tweaks to make this go faster. It did get 100% for performance though.
int solution(NSMutableArray *A)
{
NSUInteger arraySize = [A count];
NSUInteger indexOflastPrefix=0;
NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init];
for (int i=0; i<arraySize; i++)
{
if ([myDict objectForKey:[[A objectAtIndex:i]stringValue]])
{
}
else
{
[myDict setValue:#"YES" forKey:[[A objectAtIndex:i]stringValue]];
indexOflastPrefix = i;
}
}
return indexOflastPrefix;
}
int solution(vector &A) {
// write your code in C++11 (g++ 4.8.2)
int max = 0, min = -1;
int maxindex =0,minindex = 0;
min = max =A[0];
for(unsigned int i=1;i<A.size();i++)
{
if(max < A[i] )
{
max = A[i];
maxindex =i;
}
if(min > A[i])
{
min =A[i];
minindex = i;
}
}
if(maxindex > minindex)
return maxindex;
else
return minindex;
}
fwiw: Also gets 100% on codility and it's easy to understand with only one HashMap
public static int solution(int[] A) {
// write your code in Java SE 8
int firstCoveringPrefix = 0;
//HashMap stores unique keys
HashMap hm = new HashMap();
for(int i = 0; i < A.length; i++){
if(!hm.containsKey(A[i])){
hm.put( A[i] , i );
firstCoveringPrefix = i;
}
}
return firstCoveringPrefix;
}
I was looking for the this answer in JavaScript but didn't find it so I convert the Java answer to javascript and got 93%
function solution(A) {
result=0;
temp = [];
for(i=0;i<A.length;i++){
if (!temp.includes(A[i])){
temp.push(A[i]);
result=i;
}
}
return result;
}
// you can also use imports, for example:
import java.util.*;
// you can use System.out.println for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(int[] A) {
// write your code in Java SE 8
Set<Integer> s = new HashSet<Integer>();
int index = 0;
for (int i = 0; i < A.length; i++) {
if (!s.contains(A[i])) {
s.add(A[i]);
index = i;
}
}
return index;
}
}

Categories