Is this way standard to calculate the smallest number in Java - java

I wrote a program that calculate the smallest number. But I don't know how programers would do it.
I did it by "IF statement", which is working, but not sure if it is the standard or common way of coding it.
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.print("Enter three values: ");
int num1 = in.nextInt();
int num2 = in.nextInt();
int num3 = in.nextInt();
System.out.print(smallest(num1, num2, num3));
}
public static int smallest(int num1, int num2, int num3)
{
if (num1 < num2 && num1 < num3){return num1;}
else if (num2 < num1 && num2 < num3){return num2;}
else return num3;
}

There is Math#min method. You can use that one:
minimum = min(n1, min(n2, n3))

Another idea would be to not even store all of the numbers but instead just keep track of the smallest, if that's all you're looking for:
int smallest = in.nextInt();
for (int i = 0; i < 2; i++) { // take 2 more inputs
int next = in.nextInt();
if (next < smallest)
smallest = next;
}
If you indeed do not need to access inputs other than the smallest later on, this approach would likely be optimal.

You can solve the more general problem of finding the smallest value of an array (or a list). It is a bad idea to sort() the structure, as you only need to find the smallest element. A really basic technique for doing so would be something like that:
public int smallest(int[] array) {
if(array.length == 0) throw new IllegalArgumentException();
int min = array[0];
for(int i=1 ; i<array.length ; i++)
if(array[i] < min)
min = array[i];
return min;
}
This has a O(n) complexity which is minimal for a non-sorted array because you have to go through the entire array anyway.
This is of course only optimal in the general case of an array that's already full of number. If you only need to get the minimum from user's inputs then you should definitely go for arshajii's algorithm to save a bit of memory because it allows you not to store the entire array.

I would do this:
public static int smallest(int... nums) {
Arrays.sort(nums);
return nums[0];
}
Not only is it minimal elegant code, by using a varargs parameter, it can handle any quantity of ints.
And the code that calls it need not be altered.

A way of doing this is by creating an array of integers, and then sorting it and grabbing the first element.
Something like:
int[] input = new int[]{in.nextInt(), in.nextInt(), in.nextInt()};
Arrays.sort(input);
int min = input[0];
Also seeing as you have made a function for it, you could turn that one into the following, instead of my above approach:
public static int smallest(int... numbers) {
if (numbers.length == 0) {
throw new IllegalArgumentException("numbers: numbers.length == 0");
}
Arrays.sort(numbers);
return numbers[0];
}
In this example you are using varargs, meaning that you can put in as many ints as you want. The varargs argument is essentially an array once it gets into your function, so then you can just work with it like any array. Be sure to do a check on the number of items in the array though, as varargs can also be 0.
You can call the code the same way as the old one:
int smallest = smallest(5, 10, 15); will return 5.

Related

How to multiply two long values in java

I am trying to multiply two largest numbers from an array of numbers. Its working fine for small numbers.
Correct input / output - this is working:
3 10 2 8
80
Correct input / output - this is failing:
2 100000 90000
9000000000
My output is however 10000000000 instead.
Can someone tell me what is wrong in my code?
public static Long sumPairwise(Long[] numbers){
int index=0;
int n = numbers.length;
for(int i=1;i<n;i++){
if(numbers[i]>numbers[index])
index=i;
}
numbers[n-1]= numbers[index];
index=0;
for(int j=1;j<n-1;j++){
if(numbers[j]>numbers[index])
index=j;
}
numbers[n-2]=numbers[index];
Long product = (numbers[n-2])*(numbers[n-1]);
return product ;
}
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Long numbers[] = new Long[n];
for (int i=0;i<n;i++)
numbers[i]= sc.nextLong();
System.out.println(sumPairwise(numbers));
}
There is a bug in your code: numbers[n-1] may well contain the second highest number. You are overwriting that number with the highest number in your code, before you try and put it at the first to last position.
One way to overcome this is to sort the array using Arrays.sort, this way you are sure that the last two numbers are the highest and second highest number.
public static long multiplyLargestTwoNumbers(long[] numbers) {
long[] sortedNumbers = numbers.clone();
Arrays.sort(sortedNumbers);
int size = numbers.length;
// multiply highest and second highest number
return sortedNumbers[size - 1] * sortedNumbers[size - 2];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
long numbers[] = new long[n];
for (int i = 0; i < n; i++) {
numbers[i] = sc.nextLong();
}
System.out.println(multiplyLargestTwoNumbers(numbers));
}
Other changes:
using long instead of Long: try and use primitive types when the objective reference types are not needed (you need Long if you want to use e.g. a List because a List can only hold object references);
spaced out for loops, please use white space;
renamed method, as it does't add anything pairwise;
used curly braces for for loop in main method;
removed spurious parentheses in part that performs multiplication.
You might also introduce an if statement that first checks if the numbers array does indeed contain at least two elements. This is called a guard statement.
Finally remember that byte, short and long all contain signed numbers of a specific bit size. Basically you are performing calculations modulus 2^n where n is the bit size. If the value is too large it may overflow and return an incorrect result. For that you need BigInteger.
You are replacing the original number in that index with another number.
That is causing the issue.
Please just simply find the max 2 numbers from below logic and multiply.
Also, remember to close scanner.
Here the simple solution. This will work only for positive integers.
import java.util.Scanner;
public class Snippet {
public static long multiplyHighestTwoValues(Long[] numbers) {
long maxOne = 0;
long maxTwo = 0;
for (long n : numbers) {
if (maxOne < n) {
maxTwo = maxOne;
maxOne = n;
} else if (maxTwo < n) {
maxTwo = n;
}
}
long product = maxOne * maxTwo;
return product;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Long numbers[] = new Long[n];
for (int i = 0; i < n; i++)
numbers[i] = sc.nextLong();
System.out.println(sumPairwise(numbers));
sc.close();
}
}
Instead of Long try to use BigInteger to multiply larger values that fit into long, otherwise your result may overflow.
Use BigDecimal instead for multiplying floating point numbers.

How to get the largest number in an array?

I am trying to find the largest number in an array of 10 numbers. Here is my code:
public static void getNumber() {
int NumbersArray[] = new int[11];
int num1;
int num2;
int largestNumber = 0;
Scanner scanner = new Scanner(System.in);
for(int i=1; i<11; i++){
System.out.println("Enter number " + i );
int no1 = scanner.nextInt();
NumbersArray[i] = no1;
}
scanner.close();
for(int i=1; i<11; i++)
{
System.out.println(NumbersArray[i]);
num1 = NumbersArray[i];
for(int j=10; j>0; j--)
{
num2 = NumbersArray[j];
if(num1>num2){
largestNumber = num1;
}
}
}
System.out.println("the largest number is " + largestNumber);
}
I found a real simple soultion to this here.
But the reason I am posting this is to find out what mistake have I made.
The first portion gets 10 numbers from the users and the second portion is my code to find the largest number.
Going off Pshemo's suggestion, keep a record of the largest int as the user is typing. This reduces the size of your method by half and makes it much simpler and more readable.
Program with 0-based indexing. So use int NumbersArray[] = new int[10] instead of int NumbersArray[] = new int[11]. When you declare the size of your array, simply put your desired size, you don't have to worry about 0 indexing or anything. For your for-loop, start at int i=0 and end at i<10.
public static void getNumber(){
int NumbersArray[] = new int[10];
int largestNumber = 0;
Scanner scanner = new Scanner(System.in);
for(int i=0; i<10; i++){
System.out.println("Enter number " + i );
int no1 = scanner.nextInt();
NumbersArray[i] = no1;
if(no1 > largestNumber)
largestNumber = no1;
}
scanner.close();
System.out.println("The largest number is: " + largestNumber);
}
The problem is that you are iterating through the list twice (in a nested way). Let's say you have the following numbers: [5, 7, 3, 4]. As you go through the inner loop the first time you'll end up comparing numbers against 5. Only 7 is larger so largestNumber will be set to 7. Then you'll go through again, this time comparing against 7. Nothing is larger than 7, so it'll be left alone. Next you'll compare against 3. The last comparison there is 3 vs. 4, and since 4 is larger you end up setting largestNumber to 4, which is incorrect.
These lines:
for(int i=1; i<11; i++)
{
System.out.println(NumbersArray[i]);
num1 = NumbersArray[i];
for(int j=10; j>0; j--)
{
num2 = NumbersArray[j];
if(num1>num2){
largestNumber = num1;
}
}
}
Don't search for the largest number in the array, but simply search for any value in NumbersArray a value that is bigger than the current element. Thus largestNumber isn't the largest number in the array, but the last number in NumbersArray that is larger than the last element of NumbersArray, unless the last element of NumbersArray is the biggest element, in this case the largestNumber will be the last value in NumbersArray.
A working solution would be:
int max = Integer.MIN_VALUE;
for(int i : NumbersArray)
if(max < i)
max = i;
Though the most efficient solution would be to directly keep track of the currently largest input while reading the input.
And keep in mind that java-arrays are 0-based. This means that the first element is at NumbersArray[0], not NumbersArray[1], like in your code.
As far as I know you can use Java Math max() method to get largest number.
i.e. : dataType max(int number1, int number2), Math.max(number1, number2) gets the maximum between number 1 and 2.

How to recall a function, Sieve of Eratosthenes

I'm trying to write code that will work out prime numbers using the sieve of Eratosthenes. I have to include a function that will take in a number and cross of all of the multiples of that number. For testing I set the first number to be 2 and the second as 3. It works for the first number but never for the second(no matter the order of the numbers i.e if I put 3 into the function first). I know there are other completed sieve of Eratosthenes out there but I wanted to try and do it in the way that I thought of first.
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.println("Which number would you like to calculate up to?");
int n = input.nextInt();
input.close();
int x = 0;
int newNumber = 2;
int numbers[] = new int[n];
while(newNumber <= n){
numbers[x] = newNumber;
x++;
newNumber++;
}
int currentNumber = 2;
int finalNumber[] = markOfMultiples(n, numbers, currentNumber);
for(int y = 0;y < n-1;y++){
System.out.print(finalNumber[y] + ", ");
}
currentNumber = 3;
int secondNumber[] = markOfMultiples(n, numbers, currentNumber);
for(int y = 0;y < n-1;y++){
System.out.println(secondNumber[y]);
}
}
public static int[] markOfMultiples(int n, int numbers[], int currentNumber){
int originalNumber = currentNumber;
while(currentNumber<n){
currentNumber = currentNumber + originalNumber;
int count2 = 0;
while(currentNumber != numbers[count2] && currentNumber<=n && count2<n){
count2++;
}
numbers[count2] = 0;
}
return numbers;
}
The error I'm getting is: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20
at sieveOfEratosthenes.sieveOfEratosthenes.markOfMultiples(sieveOfEratosthenes.java:46)
at sieveOfEratosthenes.sieveOfEratosthenes.main(sieveOfEratosthenes.java:28)
Line 28 is when I recall the function:int secondNumber[] = markOfMultiples(n, numbers, currentNumber);
And line 46 is while(currentNumber != numbers[count2] && currentNumber<=n && count2<20){
Any help would be much appreciated. How do I keep on calling the function?
p.s. Please excuse the variable names as I'll be changing them when I get the program working.
If you want to get this approach working, you can do the fix advised by #Thierry to check count2 < n first in your while loop and then also surround the line
numbers[count2] = 0
with an if clause to check count2 is not beyond the end of the index. e.g.
if (count2 < n) {
numbers[count2] = 0;
}
Your final challenge is how you call your markOfMultiples() function enough times when n gets a bit larger. It's not a problem with your fundamental approach - you can definitely do it and your approach will work well and have acceptable performance for low-ish numbers (say up to 10000).
However
I realise this is an assignment and you want to do it your way, but there are a few features of your approach which you might want to consider - maybe after you've got it working.
Readability - is it going to be easy for someone looking at (marking) your code to understand what it's doing and verify that it will do the right thing for all values of n?
Try not to repeat yourself - for instance consider where you fill your numbers array:
while(newNumber <= n){
numbers[x] = newNumber;
x++;
newNumber++;
}
Will x ever be different to newNumber? Did you need both variables? This sort or repetition occurs elsewhere in your code - the principle to stick to is known as DRY (Don't Repeat Yourself)
Is there an easier way to move the index on originalNumber places in your markOfMultiples() method? (HINT: yes, there is)
Do you really need the actual numbers in the numbers[] array? You're going to end up with a lot of zeros and the primes left as integer values if you work out how to call your markOfMultiples repeatedly for high values of n. Would an array of 1s and 0s (or trues and falses) be enough if you used the array index to give you the prime number?
You need to test if count2 < n BEFORE access to numbers[count2]:
while(count2 < n && currentNumber != numbers[count2] && currentNumber<= n){
count2++;
}

Two smallest numbers in a set

I am trying to find the two smallest numbers in a set WITHOUT USING ARRAYS. Here is the code:
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int min = in.nextInt();
for(int i = 1; i < N; i++){
int a = in.nextInt();
if(a < min){
min = a;
}
}
System.out.println(min);
It find the smallest number but there is nothing about the second smallest number.
How do I do that?
Please, note that I am a complete beginner to Java so easy explanation and help will be much appreciated)
It´s very very easy:
Scanner in= new Scanner(System.in);
int N = in.nextInt();
int min,min2 = Integer.MAX_VALUE,Integer.MAX_VALUE;
for(int i = 0; i < N; i++){
int a = in.nextInt();
if( a < min){
min = a;
min2 = min;
}
else if( a < min2){
min2 = a;
}
}
System.out.println(min);
System.out.println(min2);
It is about one condition you have to add:
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int min = Integer.MAX_VALUE;
int secondMin = Integer.MAX_VALUE;
for(int i = 0; i < N; i++){
int a = in.nextInt();
if(a < min){
secondMin = min; // the current minimum must be the second smallest
min = a; // allocates the new minimum
}
else if (a < secondMin) {
secondMin = a; // if we did not get a new minimum, it may still be the second smallest number
}
}
System.out.println(min);
System.out.println(secondMin);
General hint: You should call the close method of your Scanner, preferably in a try-with-ressources block:
try(Scanner in = new Scanner(System.in)) {
// other code here
}
That way the stream gets closed, which you should do, if you open a stream.
Solution 1:
The easiest way, that uses your existing code, would be also tracking the second smallest number:
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int min = in.nextInt();
int sMin = Integer.MAX_VALUE;
for(int i = 1; i < N; i++){
int a = in.nextInt();
if(a < min){
sMin = min;
min = a;
} else if(a < sMin) {
sMin = a;
}
}
System.out.println(min);
System.out.println(sMin);
Explanation 1:
The two cases, that can occure with a new Value are:
The new value is smaller than min and sMin. Then you have to set the value of min into smin and afterwards set min to the new min value.
The new value is larger than min and smaller than sMin. Then you only have to set the value of sMin to the new value.
Both min-values are smaller. Then nothing is to do.
Solution 2:
Another, more generic approach would be using a PriorityQueue:
int N = in.nextInt();
PriorityQueue<Integer> minQueue = new PriorityQueue<>();
for(int i = 0; i < N; i++) {
int value = in.nextInt();
minQueue.add(value);
}
int minValue = minQueue.poll();
int secondMinValue = minQueue.poll();
This way you can get the n smallest numbers given by using a loop in which you call the poll() method. (n may be a number < N).
Explanation 2:
The Priority Queue is a datastructure, that internally orders the given elements by the natural order. In the case of Integers this order is given by <,> and =. So when calling poll() you remove the smallest element, that the PriorityQueue has yet encountered.
Try this:
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int min2 = in.nextInt();
int min1 = min2;
for(int i = 1; i < n; i++){
int a = in.nextInt();
if( a < min2){
if(a < min1){
min2 = min1;
min1 = a;
}
else{
min2 = a;
}
}
}
System.out.println(min1 + " " + min2);
This problem can be solved in multiple ways, and the first step in choosing the right solution is to decide what is the most important for you:
Space efficiency, that is, use the minimum possible amount of storage. ThreeFx does this, (s)he only uses constant additional space for the variables N, a, min, and secondMin. "Constant space" means that the amount of data that you store does not depend on how many numbers you are going to read from the stream. In contrast, Tarlen uses linear space, storing all the numbers read from the stream. This means that the amount of space required is directly proportional to N instead of being constant.
Time efficiency, that is, perform as few computations as possible. I believe that ThreeFx's solution is one of the most efficient from this point of view. Tarlen's solution will be a bit slower, because managing the priority queue might require more comparisons.
Extensibility, that is, how easily you could adapt your code when the requirements change slightly. Say that your boss makes you solve the problem that you just posted, to find the two smallest numbers. The next day, he wants the first three, and so on, until the end of the week. You get tired of changing your code every day, so you write a general solution, that will work for any number of elements that he asks for. This is where Tarlen's solution is better.
Readability, that is, how short and easy to understand your code is. I will introduce my own solution here, which is based on a simple idea: put all the numbers in a list, sort it, and take out the first two numbers. Note that this is quite wasteful when it comes to resources: the space is linear (I am storing N numbers), and the time efficiency is O(N log N) at best. Here is my code:
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < N; i++) list.add(in.nextInt());
Collections.sort(list);
System.out.println(list.get(0));
System.out.println(list.get(1));

Finding the lowest double in a Java array

I am trying to catch the lowest double from user input. I am only catching the value of the initialized min variable - what am I missing? Thanks!
public static void main(String[] args) {
double[] lowNum = new double[10];
Scanner input = new Scanner(System.in);
for (int i=0; i<=9; i++) {
System.out.println("Enter a double: ");
lowNum[i] = input.nextDouble();
}
input.close();
double min = calcLowNum(lowNum);
System.out.println(min);
}
public static double calcLowNum(double[] a) {
double min=0;
for (int i=0; i>=9; i++){
for (int j=0; j>=9; j++){
if (a[i]<=a[j] && j==9){
min=a[i];
}
else {
continue;
}
}
}
return min;
You could just use Collections#min to find the minimum value. You will need Apache Commons-Lang for this though.
// This would be the array 'a'
double[] array = {15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Convert the primitive array into a Class array
Double[] dArray = ArrayUtils.toObject(array);
List<Double> dList = Arrays.asList(dArray);
// Find the minimum value
Double returnvalue = Collections.min(dList);
return returnvalue; // or you can do returnvalue.doubleValue() if you really want
First of all, change the i>=9 and j>=9 to i<=9 and j<=9 in:
for (int i=0; i>=9; i++){
for (int j=0; j>=9; j++){
Otherwise, your loops are effectively no-ops.
A far more robust approach is to write the loops like so:
for (int i = 0; i < a.length; i++) {
or like so:
for (double val : a) {
Finally, finding the minimum can be done by iterating over the array just once, comparing each element with the current minimum (but make sure to initialize min appropriately!)
If You really need to store all inputs and than find minimal, easiest way to do it to use library function for sorting array:
...
//sorting array, so first element will be the lowest
Arrays.sort(lownum);
double min = lownum[0];
I agree with Peter Lawree You don't actually need all the array; You need to save first input and all the followings compare with it and store if lower:
double lastInput=0, min=0;
for (int i=0; i<=9; i++) {
System.out.println("Enter a double: ");
lastInput = input.nextDouble();
if (0==i) {
//if this is first iteration, save first input as min
min=lastInput;
} else {
if (lastInput<min) min=lastInput;
}
}
return min;
P.S. Actually, You should use Double.compare to compare doubles. So example with Arrays.sort() better if number of inputs not huge, in this case first example will take much more memory and time to execute.
Update: Java8 solution
double findMin(double[] input) {
return Arrays.stream(input).min().getAsDouble();
}
OMG, iterate over array - this is the worst workaround (but my bad english is more worse than it). Look at http://code.google.com/p/guava-libraries/ This lib contains robust code for your need (de-facto must have library in your project). You can see and analyze sources - it's free , but you experience in best practice will be grown as my english skills.
Below is excample of guava code:
public static double min(double... array) {
checkArgument(array.length > 0);
double min = array[0];
for (int i = 1; i < array.length; i++) {
min = Math.min(min, array[i]);
}
return min;
}
P.S: learn libraries with standart code and do not reinvent the wheel. Be happy!

Categories