Descending order of decimals - java

It is requested to sort the list below from smallest to largest.
Array input: [-100, 50, 0, 56.6, 90, 0.12, .12, 02.34, 000.000]
My Code:
import java.math.BigDecimal;
import java.util.*;
class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String[] s = new String[n + 2];
for (int i = 0; i < n; i++) {
s[i] = sc.next();
}
sc.close();
List <String> k = new ArrayList <> ();
for (int i = 0; i < s.length - 2; i++) {
k.add(s[i]);
}
Collections.sort(k, Collections.reverseOrder());
k.toArray(s);
for (int i = 0; i < n; i++) {
System.out.println(s[i]);
}
}
}
I wrote the above code but I am getting this result.
My Output: [90, 56.6, 50, 02.34, 000.000, 0.12, 0, .12, -100]
The expected result is like this.
Expected: [90, 56.6, 50, 02.34, 0.12, .12, 0, 000.000, -100]
I tried converting array into list and sort it but it was able to sort positive and negative numbers but not decimal

The problem you are running into is the fact that you are not comparing doubles, you are comparing strings. Collections.sort() will call the String.compareTo() method which is leading to the behavior you are experiencing. The following code outputs the array you were expecting.
String[] yourArray = {"-100","50","0","56.6","90","0.12",".12","02.34","000.000"};
List<Double> k = new ArrayList<>();
for (int i = 0; i < yourArray.length; i++) {
k.add(Double.parseDouble(yourArray[i]));
}
Collections.sort(k, Collections.reverseOrder());
for (int i = 0; i < k.size(); i++) {
System.out.print(k.get(i) + " ");
}

The problem is that you are just sorting the value as strings. What you want to do is sort them as if they are doubles. You need to provide a comparator that compare the double values instead of string.
import java.util.*;
public class Main{
public static void main(String[] args) {
String []s = {"-100","50","0","56.6","90","0.12",".12","02.34","000.000"};
System.out.println("Before : " + Arrays.toString(s));
Arrays.sort(s, (x,y)->Double.valueOf(y).compareTo(Double.valueOf(x)));
System.out.println("Actual : " + Arrays.toString(s));
System.out.println("Expected: [90, 56.6, 50, 02.34, 0.12, .12, 0, 000.000, -100]");
}
}
output
Before : [-100, 50, 0, 56.6, 90, 0.12, .12, 02.34, 000.000]
Actual : [90, 56.6, 50, 02.34, 0.12, .12, 0, 000.000, -100]
Expected: [90, 56.6, 50, 02.34, 0.12, .12, 0, 000.000, -100]

Your code imports BigDecimal, but doesn't use it. Try the following:
Change this:
String []s=new String[n+2];
for(int i=0;i<n;i++){
s[i]=sc.next();
}
To this:
BigDecimal [] s = new BigDecimal[n];
for(int i=0;i<n;i++){
s[i]=sc.nextBigDecimal();
}
And change
List<String> k = new ArrayList<>();
to
List<BigDecimal> k = new ArrayList<>();
Consider removing the intermediate array, and using your Scanner to put a new BigDecimal into k:
List<BigDecimal> k = new ArrayList<> ();
for (int i < 0; i < n; i++) {
k.add (sc.nextBigDecimal());
}
Note:
The sort method of Collections is stable. That means, it will not change the order of two objects that compare as equal.
BigDecimal.compareTo regards 0.00, 0.0000, and 0 as equal to each other. The values 123, 123.00, 123.000 are another example. So, in your example, if 0 precedes 000.000 before the sort, 0 will precede 000.000 after the sort. If 000.000 precedes 0 before the sort, 000.000 will precede 0 after the sort. If that is an issue for you, you can create a custom Comparator, which might use the scale method of BigDecimal. Another option is to create a custom class, which implements Comparable.

Related

How to change an integer array within a method

I am having an issue with a fill-in-the-code digital textbook problem. All the code is permanent and cannot be changed, so the problem can only be solved by using the area that states //Write code here.
The problem asks to implement the removeOdd method.
import java.util.Arrays;
public class RemoveTester
{
public static int removeOdd(int[] values, int size)
{
//Write code here
}
public static void main(String[] args)
{
int[] a = { 22, 98, 95, 46, 31, 53, 82, 24, 11, 19 };
int sizeBefore = 8;
int sizeAfter = removeOdd(a, sizeBefore);
System.out.print("a: [ ");
for (int i = 0; i < sizeAfter; i++)
{
System.out.print(a[i] + " ");
}
System.out.println("]");
System.out.println("Expected: [ 22 98 46 82 24 ]");
int[] b = { 23, 97, 95, 45, 31, 53, 81, 24, 11, 19 };
sizeBefore = 7;
sizeAfter = removeOdd(b, sizeBefore);
System.out.print("b: [ ");
for (int i = 0; i < sizeAfter; i++)
{
System.out.print(b[i] + " ");
}
System.out.println("]");
System.out.println("Expected: [ ]");
}
}
The way I tried to implement removeOdd is by doing:
int evenCount = 0;
for(int i = 0; i<size; i++){
if(values[i]%2==0){
evenCount++;
}
}
int[] newValues = new int[evenCount];
int newCount =0;
for(int i = 0; i<evenCount; i++){
if(values[i]%2==0){
newValues[newCount] = values[i];
newCount++;
}
}
values = newValues;
return evenCount;
When the program is compiled and ran, main prints the beginning of the original a or b arrays instead of only the even elements in a or b. I cannot find a way to alter the original arrays within the method removeOdd into the new arrays with only their even elements. I can't think of any other way to do this either. Any help would be greatly appreciated!
The other answers give a good description of what the problem is with your overall approach...that is, why your results don't make it back to the calling method.
If your code were otherwise correct, you could use it as is and just copy the result back into the original array at the end. As it is, you had one flaw in your logic. So if you fix that flaw, and then do the copy at the end, you should get the correct result:
public static int removeOdd(int[] values, int size)
{
int evenCount = 0;
for(int i = 0; i<size; i++){
if(values[i]%2==0){
evenCount++;
}
}
int[] newValues = new int[evenCount];
int newCount =0;
for(int i = 0; i<size; i++) { // <- Need to iterate over the entire input array
if(values[i]%2==0){
newValues[newCount] = values[i];
newCount++;
}
}
for (int i = 0 ; i < evenCount ; i++) // <- now copy your result to the original array
values[i] = newValues[i];
return evenCount;
}
Rather than creating an extra array to temporarily hold the even values, you can use the same logic to copy into the original array directly:
public static int removeOdd(int[] values, int size)
{
int newCount =0;
for(int i = 0; i<size; i++) {
if(values[i]%2==0){
values[newCount] = values[i];
newCount++;
}
}
return newCount;
}
Because Java is pass by value and not pass by reference, setting the value of the values argument will not change the value of the a variable.
What you have to do is remove all the odd elements from the array and shift the remaining even elements to the left so that the actual resultant form of a looks like this:
{22, 98, 46, 82, 24, 0, 0, 0, 0, 0}
As #Geoff pointed out Java is pass by value, which means when you pass your array as an argument, what you get inside the method is a reference to the array object which is different from the original reference int[] a you have inside your main method (the caller). Therefore, when you do values = newValues; you are pointing that new reference which used to point to the same object as int[] a to the array object newValues points to, thereby not updating the original array a but actually losing any reference to it.

In an array of int's, how can I return the index corresponding to the lowest value? [duplicate]

This question already has answers here:
Finding the index number of the lowest value in an array
(4 answers)
Closed 3 years ago.
I've managed to find the lowest value in the array with my "lowest" variable, but im looking for the index which corresponds to the lowest value in the array. Any ideas?
public class Marathon {
public static void main(String[] args) {
String[] names = { "Elena", "Thomas", "Hamilton", "Suzie", "Phil",
"Matt", "Alex", "Emma", "John", "James", "Jane",
"Emily", "Daniel", "Neda", "Aaron", "Kate" };
int[] times = { 341, 273, 278, 329, 445, 402, 388, 275, 243, 334,
412, 393, 299, 343, 317, 265 };
for (int i = 0; i < names.length; i++) {
System.out.println(names[i] + ": " + times[i]);
}
lowesttime(names, times);
}
public static void lowesttime(String names[], int times[]) {
int lowest;
lowest = times[0];
for (int i = 1; i < times.length; i++) {
if (times[i] < lowest) {
lowest = times[i];
}
}
System.out.println(lowest);
// to access arrays names[?], times[?}
// System.out.println(names[lowest] + ": " + times[lowest]);
}
}
public static void lowesttime(String[] names, int[] times) {
Pair<Integer, Integer> min = IntStream.range(0, times.length)
.mapToObj(i -> new Pair<Integer, Integer>(i, times[i]))
.reduce(new Pair<>(-1, Integer.MAX_VALUE), (r, p) ->
r.getKey() == -1 || r.getValue() > p.getValue() ? p : r);
String minName = p.getKey() == -1 ? "nobody" : names[p.getKey()];
System.out.printf("Found minimum for %s at index %d, value %d%n",
minName, min.getKey(), min.getValue());
}
I wanted to show using a Stream:
IntStream.range(0, N) will give a stream of 0, 1, 2, ..., N-1. The indices.
mapToObj converts to a Stream<Pair<Integer, Integer>> where the pairs key is the index, and the pairs value is times[index].
reduce will start with an initial pair (-1, Integer.MAX_VALUE) as result,
and then for every pair in the stream whether a better minimum can be found.
Note you could just use a pair of name and time (Pair<String, Integer>); the index is not needed.
It here might be too advanced and circumstantial, but it is both very expressive and clean (using steps without needing local variables).
You can set a variable to the index of the element, instead of just getting the value of that element;
public static void lowesttime(String[] names, int[] times) {
int lowest;
int lowestIndex = 0;
lowest = times[0];
for (int i = 1; i < times.length; i++) {
if (times[i] < lowest) {
lowest = times[i];
lowestIndex = i;
}
}
System.out.println(lowest);
System.out.println(lowestIndex);
// to access arrays names[?], times[?}
// System.out.println(names[lowest] + ": " + times[lowest]);
}
If you already know your lowest value, you can use:
java.util.Arrays.asList(theArray).indexOf(lowestValue)

Alternative ways to find Matrix min max using Java

package myArray;
// https://github.com/javadevelopcom/ArrayVsArrayList/blob/master/src/myArray/MatrixMinMax.java
public class MatrixMinMax {
public static void matrixMinMax() {
System.out.println("Matrix is a rectangular array of numbers, symbols, or expressions:" + "\n");
int[][] matrix = {
{10, 10, 10, 10, -10},
{20, 20, 20, -20, 20},
{30, 30, -30, 30, 30},
{40, -40, 40, 40, 40},
{-50, 50, 50, 50, 50}};
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) System.out.print(matrix[i][j] + " ");
System.out.println();
}
int min = matrix[0][0];
int max = matrix[0][0];
for (int[] ints : matrix) {
for (int i : ints) {
if (i < min) {
min = i;
}
if (i > max) {
max = i;
}
}
}
System.out.println("MIN: " + min);
System.out.println("MAX: " + max);
}
}
Matrix Array min max, Two-dimensional array
Although this is mere speculation, depending on overall context, it would be possible not to search maximum and minimum in the actual data member
int[][] matrix
but use some custom method to set entries; this method would perform some check against additional members
int maximum = Integer.MIN_VALUE;
int minimum = Integer.MAX_VALUE;
and replace them if necessary. Such a method could be implemented as follows, and maximum and minimum would be accessible in the members above.
void setEntry(int i, int j, in value)
{
matrix[i][j] = value;
minimum = Math.min(value, minimum);
maximum = Math.max(value, maximum);
}
However, this approach basically would trade the time for searching the matrix for time setting up the matrix entries.
i think you can't do better then O(n^2) ; since the numbers are not sorted , or do not have any particular property (like all of them fit into a certain range, for example), you must access every single number, to make sure if it does/doesn't modify the value of the existing maximum/minimum. accessing all the numbers gives n^2 operations
One of the approach is to convert a two dimensional array to 1D list and use Stream API to get the min and max value.
We would have use Integer array as against int array in the above code. Consider the following implementation. The number of lines of code is decreased.
Integer[][] matrix = {
{10, 10, 10, 10, -10},
{20, 20, 20, -20, 20},
{30, 30, -30, 30, 30},
{40, -40, 40, 40, 40},
{-50, 50, 50, 50, 50}};
List<Integer> list = new ArrayList<Integer>();
for (Integer[] array : matrix)
list.addAll(Arrays.asList(array));
int max = list.stream().max((p1, p2) -> p1.compareTo(p2)).get().intValue();
int min = list.stream().min((p1, p2) -> p1.compareTo(p2)).get().intValue();
System.out.println("MIN: " + min);
System.out.println("MAX: " + max);
This isn't exactly the answer to the question but I think it sheds some light and gives some theoretical improvement.
If you want a O(n) complexity time, you should change you nested iteration for-loop:
//in O(n^2)
for (int[] ints : matrix) {
for (int i : ints) {
if (i < min) {
min = i;
}
if (i > max) {
max = i;
}
}
}
To something like:
for(i = 0; i<(X*Y); i++)
In you case X = 5,Y = 5; and then iterate.
Or you can easilly use lambdas to find the min and max of your array like below :
public int getTheMaxOfRow(int matrix[][], int row) {
return Arrays.stream(matrix).skip(row).limit(1).flatMapToInt(d -> Arrays.stream(d)).max().getAsInt();
}
public int getTheMinOfRow(int matrix[][], int row) {
return Arrays.stream(matrix).skip(row).limit(1).flatMapToInt(d -> Arrays.stream(d)).min().getAsInt();
}

How do I pass int values from one method to another

I'm trying to find the lowest time in minutes of the array int [] times, but I can't figure out how to make the second method work; I'm not getting any output.
public static void main(String[] arguments) {
String[] names = { "Elena", "Thomas", "Hamilton", "Suzie", "Phil",
"Matt", "Alex", "Emma", "John", "James", "Emily", "Daniel",
"Neda", "Aaron", "Kate" };
int[] times = { 321, 273, 278, 329, 445, 402, 388, 275, 243, 334, 412,
393, 299, 343, 317, 265 };
for (int i = 0; i < names.length; i++)
System.out.println(names[i] + ":" + times[i]);
}
I don't know what it's missing but i know i should get the lowest time in minutes: which is 243 (int [] times). I "believe" i need to pass the int time values from the first method to the second method...since i feel the second method array is empty. However, that, i don't know how to do. Help?
public static int getMinIndex(int[] values) {
int minValue = Integer.MAX_VALUE;
int minIndex = -1;
for (int i = 0; i < values.length; i++)
if (values[i] < minValue) {
minValue = values[i];
minIndex = i;
}
return minIndex; //not returning anything.
}
The logic of your program is:
1. Declaring an array of names.
2. Declaring an array of times.
3. Writing the names and times through a loop to the console.
You also wrote a method to retrieve the minimum value within an int array,
but you did not include that in your program, which starts from the first line of the main method.
So the first question would be, where would you like to use the minimum value.
and the second question would be, what would you like to do with the minimum value.
Suppose you want to show the min value on the console,
simply write:
System.out.println(getMinValue(times));
This way the method's return value is passed to the static method of System.out as an argument, suppose you want to do something else, pass it to another method that accepts int arrays.
Write this in your main method
int min_index = getMinIndex(times);
You forget to call method. Here min_index contains the integer value that you have to return from the method.
First, I would suggest you really want a getMinValue(int... arr)
public static int getMinValue(int... values) {
// Handle null and the empty array
if (values == null || values.length < 1) {
return -1;
}
// start at the first element
int minValue = values[0];
for (int i = 1; i < values.length; i++) {
if (values[i] < minValue) {
minValue = values[i];
}
}
// return the minimum value
return minValue;
}
Then you would call it with
public static void main(String[] args) {
System.out.println(getMinValue(4, 0, 2, 3));
int[] arr = { 5, 6, 7, 8, 3, 2 };
System.out.println(getMinValue(arr));
}
Output is
0
2

sorting integers in order lowest to highest java

These numbers are stored in the same integer variable. How would I go about sorting the integers in order lowest to highest?
11367
11358
11421
11530
11491
11218
11789
There are two options, really:
Use standard collections, as explained by Shakedown
Use Arrays.sort
E.g.,
int[] ints = {11367, 11358, 11421, 11530, 11491, 11218, 11789};
Arrays.sort(ints);
System.out.println(Arrays.asList(ints));
That of course assumes that you already have your integers as an array.
If you need to parse those first, look for String.split and Integer.parseInt.
You can put them into a list and then sort them using their natural ordering, like so:
final List<Integer> list = Arrays.asList(11367, 11358, 11421, 11530, 11491, 11218, 11789);
Collections.sort( list );
// Use the sorted list
If the numbers are stored in the same variable, then you'll have to somehow put them into a List and then call sort, like so:
final List<Integer> list = new ArrayList<Integer>();
list.add( myVariable );
// Change myVariable to another number...
list.add( myVariable );
// etc...
Collections.sort( list );
// Use the sorted list
Collections.sort( List )
Well, if you want to do it using an algorithm. There are a plethora of sorting algorithms out there. If you aren't concerned too much about efficiency and more about readability and understandability. I recommend Insertion Sort. Here is the psudo code, it is trivial to translate this into java.
begin
for i := 1 to length(A)-1 do
begin
value := A[i];
j := i - 1;
done := false;
repeat
{ To sort in descending order simply reverse
the operator i.e. A[j] < value }
if A[j] > value then
begin
A[j + 1] := A[j];
j := j - 1;
if j < 0 then
done := true;
end
else
done := true;
until done;
A[j + 1] := value;
end;
end;
For sorting narrow range of integers try Counting sort, which has a complexity of O(range + n), where n is number of items to be sorted. If you'd like to sort something not discrete use optimal n*log(n) algorithms (quicksort, heapsort, mergesort). Merge sort is also used in a method already mentioned by other responses Arrays.sort. There is no simple way how to recommend some algorithm or function call, because there are dozens of special cases, where you would use some sort, but not the other.
So please specify the exact purpose of your application (to learn something (well - start with the insertion sort or bubble sort), effectivity for integers (use counting sort), effectivity and reusability for structures (use n*log(n) algorithms), or zou just want it to be somehow sorted - use Arrays.sort :-)). If you'd like to sort string representations of integers, than u might be interrested in radix sort....
import java.util.Arrays;
public class sortNumber {
public static void main(String[] args) {
// Our array contains 13 elements
int[] array = {9, 238, 248, 138, 118, 45, 180, 212, 103, 230, 104, 41, 49};
Arrays.sort(array);
System.out.printf(" The result : %s", Arrays.toString(array));
}
}
if array.sort doesn't have what your looking for you can try this:
package drawFramePackage;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Random;
public class QuicksortAlgorithm {
ArrayList<AffineTransform> affs;
ListIterator<AffineTransform> li;
Integer count, count2;
/**
* #param args
*/
public static void main(String[] args) {
new QuicksortAlgorithm();
}
public QuicksortAlgorithm(){
count = new Integer(0);
count2 = new Integer(1);
affs = new ArrayList<AffineTransform>();
for (int i = 0; i <= 128; i++){
affs.add(new AffineTransform(1, 0, 0, 1, new Random().nextInt(1024), 0));
}
affs = arrangeNumbers(affs);
printNumbers();
}
public ArrayList<AffineTransform> arrangeNumbers(ArrayList<AffineTransform> list){
while (list.size() > 1 && count != list.size() - 1){
if (list.get(count2).getTranslateX() > list.get(count).getTranslateX()){
list.add(count, list.get(count2));
list.remove(count2 + 1);
}
if (count2 == list.size() - 1){
count++;
count2 = count + 1;
}
else{
count2++;
}
}
return list;
}
public void printNumbers(){
li = affs.listIterator();
while (li.hasNext()){
System.out.println(li.next());
}
}
}
Take Inputs from User and Insertion Sort. Here is how it works:
package com.learning.constructor;
import java.util.Scanner;
public class InsertionSortArray {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
System.out.println("enter number of elements");
int n=s.nextInt();
int arr[]=new int[n];
System.out.println("enter elements");
for(int i=0;i<n;i++){//for reading array
arr[i]=s.nextInt();
}
System.out.print("Your Array Is: ");
//for(int i: arr){ //for printing array
for (int i = 0; i < arr.length; i++){
System.out.print(arr[i] + ",");
}
System.out.println("\n");
int[] input = arr;
insertionSort(input);
}
private static void printNumbers(int[] input) {
for (int i = 0; i < input.length; i++) {
System.out.print(input[i] + ", ");
}
System.out.println("\n");
}
public static void insertionSort(int array[]) {
int n = array.length;
for (int j = 1; j < n; j++) {
int key = array[j];
int i = j-1;
while ( (i > -1) && ( array [i] > key ) ) {
array [i+1] = array [i];
i--;
}
array[i+1] = key;
printNumbers(array);
}
}
}

Categories