Getting the second highest and second lowest java - java

Getting the second highest and second lowest java without using array array sort or any sorting method, min_value and max_value just for loop and if statement I already started to code this is what ive done so far i cant think of how can i get the second lowest and second highest
package Lab2;
import java.util.Scanner;
public class hehe {
public static void main(String[] args) {
int fh, sh, fl, sl, x;
Scanner s = new Scanner(System.in);
System.out.print("Enter 5 numbers: ");
x = fh = sh = sl = fl = s.nextInt();
int a,b,c,d;
int mid = 0;
for (int i = 0; i < 4; ++i) {
int n = s.nextInt();
if (fh < n) {
fh = n;
}
if (fl > n) {
fl = n;
}
for(int y=0;y<5;y++){
}
}
System.out.println("The First highest is: " + fh);
System.out.println("The Second highest is: " + sh);
System.out.println("The Second lowest is: " + sl);
System.out.println("The First lowest is: " + fl);
System.out.println(mid);
}
}

Just improve upon your condition to cover all cases,
// Initialize your variables like this,
fh = sh = Integer.MIN_VALUE;
fl = sl = Integer.MAX_VALUE;
// Change your for loop condition to below and get input only inside the loop. Not before it.
for (int i = 0; i < 5; ++i) {
if (fh < n) { // It means you have received the highest known number
sh = fh; // The existing highest becomes the second highest now
fh = n; // n should now be the (first) highest rightfully
} else if (sh < n) { // This means n was not the highest, but second highest
sh = n;
}
// Do the same for lowest also.

Obviously, sorting the array is the obvious solution so I assume this is some sort of test assignment. Anyway, I guess the easiest way is just to have variables for both highest and 2nd highest (and same for lowest). For example, to find the 2nd highest:
List<Integer> values = new ArrayList<>();
for(int i = 0; i < 20; i++) {
values.add((int) (Math.random() * 10));
}
int highest = Integer.MIN_VALUE;
int second = Integer.MIN_VALUE;
for(int n: values) {
if(n > highest) {
second = highest;
highest = n;
} else if(n > second) {
second = n;
}
}
System.out.println("2nd highest: " + second);

if (fh < n) {
sh = fh;
fh = n;
}else if (sh < n)
{
sh = n;
}
if (fl > n) {
s1=f1
fl = n;
}else if (s1 > n)
{
s1 = n;
}

You need to also update the value of variable accordingly:
public static void main(String[] args) {
int fh, sh, fl, sl, x;
Scanner s = new Scanner(System.in);
System.out.print("Enter 5 numbers: ");
x = fh = sh = sl = fl = s.nextInt();
int a,b,c,d;
int mid = 0;
for (int i = 0; i < 4; ++i) {
int n = s.nextInt();
if (fh < n) {
sh = fh; // We have got new fh so sh is old value of fh.
fh = n;
}
if (fl > n) {
sl = fl;
fl = n;
}
}
System.out.println("The First highest is: " + fh);
System.out.println("The Second highest is: " + sh);
System.out.println("The Second lowest is: " + sl);
System.out.println("The First lowest is: " + fl);
}

Related

Java How do i repeat sort until no swaps are done in bubblesort?

I am taking 10 elements and performing a bubble sort on them. I want to add an algorithm that repeats the sort until no swaps are needed to make this more efficient.
Essentially I want to:
repeat until no swaps done in a pass
For elements 1 to (n-1)
compare contents of element value 1 with the contents of the next value
if value 1 is greater than value 2
then swap the values
This is what I have done so far :
{
//create array
int[] iList = new int[10];
Scanner sc = new Scanner(System.in);
//takes in array input for 10 numbers
System.out.println("Enter a array of numbers ");
for(int i = 0; i< 10; i++ )
{
int num = i + 1;
System.out.println("Enter number " + num);
iList[i] = sc.nextInt();
}
//Bubble sorts the array
System.out.println("The array =");
for(int a = 0; a < iList.length; a++ )
{
for(int b = a+1; b < iList.length; b++)
{
if(iList[a] > iList[b])
{
int iTemp = iList[a];
iList[a] = iList[b];
iList[b] = iTemp;
}
System.out.println("Progress = " + Arrays.toString(iList) );
}
}
} ```
Here is my implementation :
public static void sort(int[] nums) {
boolean isSwapped;
int size = nums.length - 1;
for (int i = 0; i < size; i++) {
isSwapped = false;
for (int j = 0; j < size - i; j++) {
if (nums[j] > nums[j+1]) {
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
isSwapped = true;
}
}
if (!isSwapped) break;
}
System.out.println("Sorted Array: " + Arrays.toString(nums));
}

Adding 1 to Integer.MAX_VALUE in a loop causes unexpected behaviour (not the one where it goes to Integer.MIN_VALUE)

I was working on a HackerRank challenge for "Array Manipulation", and there was an unexpected, interesting problem encountered. I'm running a big for loop, where I'm adding prefix sums, and the moment I pass over Integer.MAX_Value in the prefix sum (where the sum is stored as an int), the number jumps down by a few thousand instead of looping into the negative which is my expected behaviour.
Anyone know why this could be occuring? There is no problem if you store the prefix sum as a long.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ArrayManipulation {
public static long arrayManipulationPrefixSumLong(int n, int[][] queries) {
long[] array = new long[n];
for (int i = 0; i < queries.length; i++) {
int lowIndex = queries[i][0] - 1;
int highIndex = queries[i][1] - 1;
int addend = queries[i][2];
array[lowIndex] += addend;
if (highIndex + 1 < n)
array[highIndex + 1] -= addend;
}
long maxInt = 0;
for (int i = 0; i < array.length; i++) {
if (i != 0)
array[i] = array[i - 1] + array[i];
if (array[i] > maxInt)
maxInt = array[i];
}
return maxInt;
}
public static int arrayManipulationPrefixSumInt(int n, int[][] queries) {
int[] array = new int[n];
for (int i = 0; i < queries.length; i++) {
int lowIndex = queries[i][0] - 1;
int highIndex = queries[i][1] - 1;
int addend = queries[i][2];
array[lowIndex] += addend;
if (highIndex + 1 < n)
array[highIndex + 1] -= addend;
}
int maxInt = 0;
for (int i = 0; i < array.length; i++) {
if (i != 0)
array[i] = array[i - 1] + array[i];
if (array[i] > maxInt)
maxInt = array[i];
}
return maxInt;
}
public static void main(String[] args) {
Scanner scanner = null;
try {
scanner = new Scanner(new File("input10ArrayManipulation_Subset85545.txt"));
// scanner = new Scanner(new File("input10ArrayManipulation.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int n = scanner.nextInt();
// System.out.println(n);
int qn = scanner.nextInt();
// System.out.println(qn);
int[][] queries = new int[qn][3];
for (int i = 0; i < qn; i++) {
queries[i] = new int[]{scanner.nextInt(), scanner.nextInt(), scanner.nextInt()};
}
scanner.close();
System.out.println(new String(new char[85]).replace("\0", "*"));
System.out.println("Trying to find why exceeding Integer.MAX_VALUE in a loop causes unexpected behaviour.");
System.out.println(new String(new char[60]).replace("\0", "-"));
//Relevant part
long arrayManipulationPrefixSumLong = arrayManipulationPrefixSumLong(n, queries);
int arrayManipulationPrefixSumInt = arrayManipulationPrefixSumInt(n, queries);
//Notice these two give different values
System.out.println("The long version: " + arrayManipulationPrefixSumLong);
System.out.println("The int version: " + arrayManipulationPrefixSumInt);
// Adding past the max value in a loop doesn't result in a negative number,
// to see this behaviour, increment the last line of input10ArrayManipulation_Subset85545 by 1.
System.out.println(Integer.MAX_VALUE - arrayManipulationPrefixSumLong);
//The below is my expected behaviour, where integer overflow occurs.
System.out.println("Max integer is: " + Integer.MAX_VALUE + " | Max integer +1 is: " + (Integer.MAX_VALUE + 1));
System.out.println(new String(new char[60]).replace("\0", "-"));
System.out.println("Now testing with the other file that has 1 incremented on the last line, which makes it exceed the Integer.MAX_VALUE");
try {
scanner = new Scanner(new File("input10ArrayManipulation_Subset85545_increment1.txt"));
n = scanner.nextInt();
// System.out.println(n);
qn = scanner.nextInt();
// System.out.println(qn);
queries = new int[qn][3];
for (int i = 0; i < qn; i++) {
queries[i] = new int[]{scanner.nextInt(), scanner.nextInt(), scanner.nextInt()};
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
arrayManipulationPrefixSumLong = arrayManipulationPrefixSumLong(n, queries);
arrayManipulationPrefixSumInt = arrayManipulationPrefixSumInt(n, queries);
//Notice these two give different values
System.out.println("The long version: " + arrayManipulationPrefixSumLong);
System.out.println("The int version: " + arrayManipulationPrefixSumInt);
scanner.close();
}
}
The text files used to test this program can be found at:
https://drive.google.com/drive/folders/1ktlEixYsqeD2l4x12iD4gEVvM-1gVetK?usp=sharing

How to quit scanner when input is negative?

This is the instructions.
Write a program that reads a sequence of input values and displays a bar chart of the values using asterisks. You may assume that all values are positive. First figure out the maximum value. That's value's bar should be drawn with 40 asterisks. Shorter bars should use proportionally fewer asterisks.
This is what I came up so far. It's all good except I need to enter a letter instead of a negative number to quit scanning. I have tried (if( < 0) things) but those didn't work.
import java.util.Scanner;
public class BarChart1 {
public static void main(String [] args) {
int[] arr = new int[100];
int currentSize = 0;
System.out.println("Enter a sequence of positive integers. "
+ ("Enter a negative value to quit:"));
Scanner in = new Scanner(System.in);
while(in.hasNextInt()) {
int num = in.nextInt();
if (num < 0) {
break;
}
else {
arr[currentSize] = in.nextInt();
currentSize++;
}
}
//will find the max
double max = arr[0];
int y = 0;
for (int i = 1; i < arr.length; i++) {
y = i + 1;
if(max < arr[i]) {
max = arr[i];
//y = i + 1;
}
}
System.out.println("Max number is: " + max);
System.out.println("Number of digits = " + y);
System.out.println(Math.abs(-1));
double scale = 40/max;
System.out.println("Scale = " + scale);
for (int i = 0; i < y; i++) {
double h = scale * arr[i];
if (h != 0) {
for (int j = 1; j <= h; j ++) {
System.out.print("*");
}
System.out.println();
}
}
}
}
This is the result.
1
2
3
4
-1
Max number is: 4.0
Number of digits = 100
Scale = 10.0
********************
****************************************
I only need the asterisks. Everything else that is being printed is just for checking purposes.
You can try this:
while(in.hasNextInt()) {
int num =in.nextInt();
if(num <0){
break;
}
else{
arr[currentSize] = num;
currentSize++;
}
}

Why does the order of input to this LCM finding program change the output?

import java.util.List;
import java.util.Scanner;
import java.util.ArrayList;
class LCM {
static int GCF(int first, int second){
int FIR = first;
int SEC = second;
ArrayList<Integer> prime1 = new ArrayList<Integer>();
ArrayList<Integer> prime2 = new ArrayList<Integer>();
int n = 1;
// for the specific case of 2
while(true){
if(FIR % 2 == 0){
FIR /= 2;
prime1.add(2);
}
else break;
}
// for the rest of the prime numbers
for(int i = 3;;i = 2*n + 1){
if(FIR < i) break;
if(FIR == i) {
prime1.add(i);
break;
}
if(FIR % i == 0){
FIR /= i;
prime1.add(i);
}
++n;
}
// initialize n back to 1
n = 1;
// for the specific case of 2
while(true){
if(SEC % 2 == 0){
SEC /= 2;
prime2.add(2);
}
else break;
}
// for the rest of the prime numbers
for(int i = 3;; i = 2*n + 1){
if(SEC < i) break;
if(SEC == i){
prime2.add(i);
break;
}
if(SEC % i == 0){
SEC /= i;
prime2.add(i);
}
++n;
}
// Collect all common prime factors to calculate GCF
List<Integer> common = new ArrayList<Integer>(prime2);
common.retainAll(prime1);
int GCF = 1;
for(int i = 0; i < common.size(); i++){
GCF *= common.get(i);
}
return GCF;
}
// End of LCP function
static int lcp(int first, int second){
return (first / GCF(first, second)) * second;
}
public static void main(String args[]){
Scanner input = new Scanner(System.in);
int first = 0;
int second = 0;
while(true){
System.out.print("Enter first number: ");
first = input.nextInt();
System.out.print("Enter second number: ");
second = input.nextInt();
System.out.print("LCM (" + first + ", " + second + ")" + " = ");
System.out.print(lcp(first, second) + "\n");
}
}
}
The code works perfectly when I give it input in one order but it give's the wrong output when I reverse the order of input. For example it outputs
LCM(12, 10) = 56
when I input the two numbers in the order 12 then 10. But it outputs
LCM(10, 12) = 24
when the input is reversed. I tried debugging the code but I couldn't see any obvious problem.
LCM of (10, 12) is 60, NOT 56
If you wish to calculate the LCM of two numbers entered by the user, here's a simpler version that calculates the LCM
class LCM {
public static void main(String args[]){
Scanner input = new Scanner(System.in);
int first = 0;
int second = 0;
while(true){
System.out.print("Enter first number: ");
first = input.nextInt();
System.out.print("Enter second number: ");
second = input.nextInt();
System.out.print("LCM ("+first + ","+second+") = " +lcp(first, second) + "\n");
}
}
public static int gcf(int first, int second) {
HashSet<Integer> firstFactors = new HashSet<>();
HashSet<Integer> secondFactors = new HashSet<>();
HashSet<Integer> commonFactors;
//factors of first number
for(int i=1; i<=first; i++) {
if(first%i == 0) {
firstFactors.add(i);
}
}
//factors of second number
for(int i=1; i<=second; i++) {
if(second%i == 0) {
secondFactors.add(i);
}
}
commonFactors = new HashSet<>(firstFactors);
commonFactors.retainAll(secondFactors);
return Collections.max(commonFactors);
}
static int lcp(int first, int second){
return (first / gcf(first, second)) * second;
}
}

JAVA: Passing an array to a method

I can't seem to pass my array to a secondary method. It only sees one of the 10 inputs, so I can't properly use it in the secondary method.
public static void main(String[] args) {
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.println("Enter some numbers: ");
double [] numbers = new double [10];
int n = 0;
int i = 0;
while(n < numbers.length) {
numbers[i] = input.nextDouble();
n+=1;
}
System.out.println(min(numbers));
}
public static double min(double[] array) {
System.out.println(array[1]);
double smallest = array[0];
for (int l = 1; l < array.length; l++) {
if (array[l] < smallest) {
smallest = array[l];
System.out.println("Your smallest = " + smallest);
}
}
return 0;
}
In the first while loop, the variable i does not change.
while (n < numbers.length) {
numbers[i] = input.nextDouble();
n+=1;
}
variable i is never being changed so you are assigning each new number to the same spot in the array overwriting the previous number.
Just use your n variable instead:
while (n < numbers.length) {
numbers[n] = input.nextDouble();
n += 1;
}

Categories

Resources