Here is the code:
public static int MaxProduct(int... a){ // the max possible product from an array
int i = 0;
int j = 0;
int m = 0;
int n = a.length;
while (i<n){
j++;
while(j<n ){
if (a[i]*a[j] > m){
m = a[i]*a[j];
j++;
}
}
i++;
}
return m;
}
System.out.println(MaxProduct(1,2,3,4,5));
The algorithm seems to work as expected (after check and making a table of the debugger). For the first index of an array it checks all possible products and edits m accordingly from 1 through to 5. And then once j is equal to 5 a[j]understandably is out of bounds since there are only 5 elements in the array
I then see the arrayoutofbounds error in the debugger beside (again which is what id expect) but instead of i increasing, and the second while loop starting the cycle again, a[i] stays as 1, the algorithm concludes, and i get the output 5
How do i get this to output 20 (4x5)
You need to make two changes. Check below 2 TODOs.
public static int MaxProduct(int... a) { // the max possible product from an array
int i = 0;
int j = 0;
int m = 0;
int n = a.length;
while (i < n) {
j = i + 1; // TODO: 1
while (j < n) {
if (a[i] * a[j] > m) {
m = a[i] * a[j];
}
j++; // TODO:2
}
i++;
}
return m;
}
Related
So right now I am trying to code a function that will remove the highest value in an unsorted array.
Currently the code looks like this:
#Override
public void remove() throws QueueUnderflowException {
if (isEmpty()) {
throw new QueueUnderflowException();
} else {
int priority = 0;
for (int i = 1; i < tailIndex; i++) {
while (i > 0 && ((PriorityItem<T>) storage[i - 1]).getPriority() < priority)
storage[i] = storage[i + 1];
i = i - 1;
}
/*int max = array.get(0);
for (int i = 1; i < array.length; i++) {
if (array.get(i) > max) {
max = array.get(i);
}*/
}
tailIndex = tailIndex - 1;
}
Here I have my attempt at this:
int priority = 0;
for (int i = 1; i < tailIndex; i++) {
while (i > 0 && ((PriorityItem<T>) storage[i - 1]).getPriority() < priority)
storage[i] = storage[i + 1];
i = i - 1;
The program runs no bother but still deletes the first item in the array instead of the highest number. This code was given my my college lecturer for a different solution but unfortunately it doesn't work here.
Would this solution work with enough altercations? Or is there another solution I should try?
Thanks.
The code snippet in the question can be updated to below code, while keeping the same data structure i.e. queue and this updated code has 3 steps - finding the index of largest element, shifting the elements to overwrite the largest element and finally set the tailIndex to one less i.e. decrease the size of the queue.
#Override
public void remove() throws QueueUnderflowException {
if (isEmpty()) {
throw new QueueUnderflowException();
} else {
int priority = 0;
int largeIndex = 0;
for (int i = 0; i < tailIndex; i++) {
if (((PriorityItem<T>) storage[i]).getPriority() > priority) {
priority = ((PriorityItem<T>) storage[i]).getPriority();
largeIndex = i ;
}
}
for(int i = largeIndex; i < (tailIndex - 1) ; i++)
storage[i] = storage[i + 1];
}
tailIndex = tailIndex - 1;
}
Hope it helps.
Step 1
Find the highest index.
int[] array;
int highIndex = 0;
for (int i = 1; i < highIndex.size(); i++)
if (array[highIndex] < array[highIndex])
highIndex = i;
Step 2
Create new array with new int[array.size() - 1]
Step 3
Move all values of array into new array (except the highest one).
My hint: When its possible, then use a List. It reduces your complexity.
You can find the largest Number and it's index then copy each number to its preceding number. After that, you have two options:
Either add Length - 1 each time you iterate the array.
Or copy the previous array and don't include removed number in it.
Working Code:
import java.util.Arrays;
public class stackLargest
{
public static void main(String[] args)
{
int[] unsortedArray = {1,54,21,63,85,0,14,78,65,21,47,96,54,52};
int largestNumber = unsortedArray[0];
int removeIndex = 0;
// getting the largest number and its index
for(int i =0; i<unsortedArray.length;i++)
{
if(unsortedArray[i] > largestNumber)
{
largestNumber = unsortedArray[i];
removeIndex = i;
}
}
//removing the largest number
for(int i = removeIndex; i < unsortedArray.length -1; i++)
unsortedArray[i] = unsortedArray[i + 1];
// now you have two options either you can iterate one less than the array's size
// as we have deleted one element
// or you can copy the array to a new array and dont have to add " length - 1" when iterating through the array
// I am doing both at once, what you lke you can do
int[] removedArray = new int[unsortedArray.length-1];
for(int i =0; i<unsortedArray.length-1;i++)
{
System.out.printf(unsortedArray[i] + " ");
removedArray[i] = unsortedArray[i];
}
}
}
Note: Use List whenever possible, it will not only reduce complexity, but, comes with a very rich methods that will help you a big deal.
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
I am defining a function to accept a matrix (2d array), for example x[][]; and the function should print the biggest even number in each line
public static void biggestEvenNumOfEachLine(int x[][]){
int even,t=0,max;
int arr[] = new int [x.length];
for(int i = 0; i < x.length;i++){
for(int j = 0; j < x[i].length;j++,t++){
if(x[i][j] % 2 == 0){
even = x[i][j];
arr[j] = even;
}
}
}
}
What am I missing?
I would start by finding the biggest even number in a single line array. Start with the smallest possible value, and then iterate the array. Test for even, and then set the max (and then return it). Something like,
private static int biggestEvenNum(int[] x) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < x.length; i++) {
if (x[i] % 2 == 0) {
max = Math.max(max, x[i]);
}
}
return max;
}
But, in Java 8+, I would prefer to filter for even values and get the max like
private static int biggestEvenNum(int[] x) {
return IntStream.of(x).filter(v -> v % 2 == 0).max().getAsInt();
}
Then your method is as simple as iterating the line(s) in your matrix, printing the result. Like,
public static void biggestEvenNumOfEachLine(int[][] x) {
for (int[] line : x) {
System.out.println(biggestEvenNum(line));
}
}
public static void biggestEvenNumOfEachLine(int x[][])
{
int arr[] = new int [x.length];
for(int i = 0; i < x.length;i++)
for(int j = 0; j < x[i].length;j++)
if(x[i][j] % 2 == 0 && x[i][j] > arr[i]){
arr[i] = x[i][j];
System.out.println(arr[i]);
}
}
This will work but if there is no even number at particular line then corresponding number to that line will be zero.
I how can I find the positions of the three lowest integers in an array?
I've tried to reverse it, but when I add a third number, it all goes to hell :p
Does anybody manage to pull this one off and help me? :)
EDIT: It would be nice to do it without changing or sorting the original array a.
public static int[] lowerThree(int[] a) {
int n = a.length;
if (n < 2) throw
new java.util.NoSuchElementException("a.length(" + n + ") < 2!");
int m = 0; // position for biggest
int nm = 1; // position for second biggest
if (a[1] > a[0]) { m = 1; nm = 0; }
int biggest = a[m]; // biggest value
int secondbiggest = a[nm]; // second biggest
for (int i = 2; i < n; i++) {
if (a[i] > secondbiggest) {
if (a[i] > biggest) {
nm = m;
secondbiggest = biggest;
m = i;
biggest = a[m];
}
else {
nm = i;
secondbiggest = a[nm];
}
}
} // for
return new int[] {m,nm};
}
EDIT: I've tried something here but it still doesn't work. I get wrong output + duplicates...
public static int[] lowerthree(int[] a) {
int n= a.length;
if(n < 3)
throw new IllegalArgumentException("wrong");
int m = 0;
int nm = 1;
int nnm= 2;
int smallest = a[m]; //
int secondsmallest = a[nm]; /
int thirdsmallest= a[nnm];
for(int i= 0; i< lengde; i++) {
if(a[i]< smallest) {
if(smalles< secondsmallest) {
if(secondsmallest< thirdsmallest) {
nnm= nm;
thirdsmallest= secondsmallest;
}
nm= m;
secondsmallest= smallest;
}
m= i;
smallest= a[m];
}
else if(a[i] < secondsmallest) {
if(secondsmallest< thirdsmallest) {
nnm= nm;
thirdsmallest= secondsmallest;
}
nm= i;
secondsmallest= a[nm];
}
else if(a[i]< thirdsmallest) {
nnm= i;
thirdsmallest= a[nnm];
}
}
return new int[] {m, nm, nnm};
}
Getting the top or bottom k is usually done with a partial sort. There are versions that change the original array and those that dont.
If you only want the bottom (exactly) 3 and want to get their positions, not the values, your solution might be the best fit. This is how I would change it to support the bottom three. (I have not tried to compile and run, there may be little mistakes but the genereal idea should fit)
public static int[] lowerThree(int[] a) {
if (a.length < 3) throw
new java.util.NoSuchElementException("...");
int indexSmallest = 0;
int index2ndSmallest = 0;
int index3rdSmallest = 0;
int smallest = Integer.MAX_VALUE;
int sndSmallest = Integer.MAX_VALUE;
int trdSmallest = Integer.MAX_VALUE;
for (size_t i = 0; i < a.length; ++i) {
if (a[i] < trdSmallest) {
if (a[i] < sndSmallest) {
if (a[i] < smallest) {
trdSmallest = sndSmallest;
index3rdSmallest = index2ndSmallest;
sndSmallest = smallest;
index2ndSmallest = indexSmallest;
smallest = a[i];
indexSmallest = i;
continue;
}
trdSmallest = sndSmallest;
index3rdSmallest = index2ndSmallest;
sndSmallest = a[i];
index2ndSmallest = i;
continue;
}
trdSmallest = a[i];
index3rdSmallest = i;
}
}
return new int[] {indexSmallest, index2ndSmallest, index3rdSmallest};
}
This will have the three lowest numbers, need to add some test cases..but here is the idea
int[] arr = new int[3];
arr[0] = list.get(0);
if(list.get(1) <= arr[0]){
int temp = arr[0];
arr[0] = list.get(1);
arr[1] = temp;
}
else{
arr[1] = list.get(1);
}
if(list.get(2) < arr[1]){
if(list.get(2) < arr[0]){
arr[2] = arr[1];
arr[1] = arr[0];
arr[0] = list.get(2);
}
else{
arr[2] = arr[1];
arr[1] = list.get(2);
}
}else{
arr[2] = list.get(2);
}
for(int integer = 3 ; integer < list.size() ; integer++){
if(list.get(integer) < arr[0]){
int temp = arr[0];
arr[0] = list.get(integer);
arr[2] = arr[1];
arr[1] = temp;
}
else if(list.get(integer) < arr[1]){
int temp = arr[1];
arr[1] = list.get(integer);
arr[2] = temp;
}
else if(list.get(integer) <= arr[2]){
arr[2] = list.get(integer);
}
}
I'd store the lowest elements in a LinkedList, so it is not fixed on the lowest 3 elements. What do you think?
public static int[] lowest(int[] arr, int n) {
LinkedList<Integer> res = new LinkedList();
for(int i = 0; i < arr.length; i++) {
boolean added = false;
//iterate over all elements in the which are of interest (n first)
for(int j = 0; !added && j < n && j < res.size(); j++) {
if(arr[i] < res.get(j)) {
res.add(j, i); //the element is less than the element currently considered
//one of the lowest n, so insert it
added = true; //help me get out of the loop
}
}
//Still room in the list, so let's append it
if(!added && res.size() < n) {
res.add(i);
}
}
//copy first n indices to result array
int[] r = new int[n];
for(int i = 0; i < n && i < res.size(); i++) {
r[i] = res.get(i);
}
return r;
}
In simple words, you need to compare every new element with the maximum of the three you have at hand, and swap them if needed (and if you swap, max of the three has to be recalculated).
I would use 2 arrays of size 3 each:
arrValues = [aV1 aV2 aV3] (reals)
arrPointers = [aP1 aP2 aP3] (integers)
and a 64 bit integer type, call it maxPointer.
I will outline the algorithm logic, since I am not familiar with Java:
Set arrValues = array[0] array[1] array[2] (three first elements of your array)
Set arrPointers = [0 1 2] (or [1 2 3] if your array starts from 1)
Iterate over the remaining elements. In each loop:
Compare the Element scanned in this iteration with arrValues[maxPointer]
If Element <= arrValues[maxPointer],
remove the maxPointer element,
find the new max element and reset the maxPointer
Else
scan next element
End If
Loop
At termination, arrPointers should have the positions of the three smallest elements.
I hope this helps?
There is an easy way to find the positions of three lowest number in an Array
Example :
int[] arr={3,5,1,2,9,7};
int[] position=new int[arr.length];
for(int i=0;i<arr.length;i++)
{
position[i]=i;
}
for(int i=0;i<arr.length;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[i]>arr[j]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
int tem=position[i];
position[i]=position[j];
position[j]=tem;
}
}
}
System.out.println("Lowest numbers in ascending order");
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
System.out.println("And their previous positions ");
for(int i=0;i<arr.length;i++)
{
System.out.println(position[i]);
}
Output
you can do it in 3 iterations.
You need two extra memory, one for location and one for value.
First iteration, you will keep the smallest value in one extra memory and its location in the second. As you are iterating, you compare every value in the slot with the value slot you keep in the memory, if the item you are visiting is smaller than what you have in your extra value slot, you replace the value as well as the location.
At the end of your first iteration, you will find the smallest element and its corresponding location.
You do the same for second and third smallest.
I have to find 1st, 2nd, and 3rd largest array. I know I could simply sort it and return array[0], array[1], array[3]. But the problem is, i need the index, not the value.
For example if i have float[] listx={8.0, 3.0, 4.0, 5.0, 9.0} it should return 4, 0, and 3.
Here's the code I have but it doesn't work:
//declaration max1-3
public void maxar (float[] listx){
float maxel1=0;
float maxel2=0;
float maxel3=0;
for (int i=0; i<listx.length; i++){
if(maxel1<listx[i])
{maxel1=listx[i];
max1=i;
}
}
listx[max1]=0; //to exclude this one in nextsearch
for (int j=0; j<listx.length; j++){
if(listx[j]>maxel2)
{maxel2=listx[j];
max2=j;
}
}
listx[max2]=0;
for (int k=0; k<listx.length; k++){
if(listx[k]>maxel3)
{maxel3=listx[k];
max3=k;
}
}
}
I get max1 right but after that all the elements turns to 0. hence max2 and max3 become 0. Please suggest me what is wrong with this solution. Thank you.
You can find the three elements using a single loop, and you don't need to modify the array.
When you come across a new largest element, you need to shift the previous largest and the previous second-largest down by one position.
Similarly, when you find a new second-largest element, you need to shift maxel2 into maxel3.
Instead of using the three variables, you might want to employ an array. This will enable you to streamline the logic, and make it easy to generalize to k largest elements.
Make 3 passes over array: on first pass find value and 1st index of maximum element M1, on second pass find value and 1st index of maximum element M2 which is lesser than M1 and on third pass find value/1st index M3 < M2.
Try this code it will work :)
public class Array
{
public void getMax( double ar[] )
{
double max1 = ar[0]; // Assume the first
double max2 = ar[0]; // element in the array
double max3 = ar[0]; // is the maximum element.
int ZERO = 0;
// Variable to store inside it the index of the max value to set it to zero.
for( int i = 0; i < ar.length; i++ )
{
if( ar[i] >= max1)
{
max1 = ar[i];
ZERO = i;
}
}
ar[ZERO] = 0; // Set the index contains the 1st max to ZERO.
for( int j = 0; j < ar.length; j++ )
{
if( ar[j] >= max2 )
{
max2 = ar[j];
ZERO = j;
}
}
ar[ZERO] = 0; // Set the index contains the 2st max to ZERO.
for( int k = 0; k < ar.length; k++ )
{
if( ar[k] >= max3 )
{
max3 = ar[k];
ZERO = k;
}
}
System.out.println("1st max:" + max1 + ", 2nd: " +max2 + ",3rd: "+ max3);
}
public static void main(String[] args)
{
// Creating an object from the class Array to be able to use its methods.
Array array = new Array();
// Creating an array of type double.
double a[] = {2.2, 3.4, 5.5, 5.5, 6.6, 5.6};
array.getMax( a ); // Calling the method that'll find the 1st max, 2nd max, and and 3rd max.
}
}
I suggest making a single pass instead of three for optimization. The code below works for me. Note that the code does not assert that listx has at least 3 elements. It is up to you to decide what should happen in case it contains only 2 elements or less.
What I like about this code is that it only does one pass over the array, which in its best case would have faster running time compared to doing three passes, with a factor proportionate to the number of elements in listx.
Assume i1, i2 and i3 store the indices of the three greatest elements in listx, and i0 is one of i1, i2 and i3 that points to the smallest element. In the beginning, i1 = i2 = i3 because we haven't found the largest elements yet. So let i0 = i1. If we find a new index j such that that listx[j] > listx[i0], we set i0 = j, replacing that old index with an index that leads to a greater element. Then we find the index among i1, i2 and i3 that now leads to the smallest element of out the three, so that we can safely discard that one in case a new large element comes along.
Note: This code is in C, so translate it to Java if you want to use it. I made sure to use similar syntax to make that easier. (I wrote it in C because I lacked a Java testing environment.)
void maxar(float listx[], int count) {
int maxidx[3] = {0};
/* The index of the 3rd greatest element
* in listx.
*/
int max_3rd = 0;
for (int i = 0; i < count; i++) {
if (listx[maxidx[max_3rd]] < listx[i]) {
/* Exchange 3rd greatest element
* with new greater element.
*/
maxidx[max_3rd] = i;
/* Find index of smallest maximum. */
for (int j = (max_3rd + 1) % 3; j != max_3rd; j = (j + 1) % 3) {
if (listx[maxidx[j]] < listx[maxidx[max_3rd]]) {
max_3rd = j;
}
}
}
}
/* `maxidx' now contains the indices of
* the 3 greatest values in `listx'.
*/
printf("3 maximum elements (unordered):\n");
for (int i = 0; i < 3; i++) {
printf("index: %2d, element: %f\n", maxidx[i], listx[maxidx[i]]);
}
}
public class ArrayExample {
public static void main(String[] args) {
int secondlargest = 0;
int thirdLargest=0;
int largest = 0;
int arr[] = {5,4,3,8,12,95,14,376,37,2,73};
for (int i = 0; i < arr.length; i++) {
if (largest < arr[i]) {
secondlargest = largest;
largest = arr[i];
}
if (secondlargest < arr[i] && largest != arr[i])
secondlargest = arr[i];
if(thirdLargest<arr[i] && secondlargest!=arr[i] && largest!=arr[i] && thirdLargest<largest && thirdLargest<secondlargest)
thirdLargest =arr[i];
}
System.out.println("Largest number is: " + largest);
System.out.println("Second Largest number is: " + secondlargest);
System.out.println("third Largest number is: " + thirdLargest);
}
}
def third_mar_array(arr):
max1=0
max2=0
max3=0
for i in range(0,len(arr)-1):
if max1<arr[i]:
max1=arr[i]
max_in1=i
arr[max_in1]=0
for j in range(0,len(arr)-1):
if max2<arr[j]:
max2=arr[j]
max_in2=j
arr[max_in2]=0
for k in range(0,len(arr)-1):
if max3<arr[k]:
max3=arr[k]
max_in3=k
#arr[max_in3]=0
return max3
n=[5,6,7,3,2,1]
f=first_array(n)
print f
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int testcase = sc.nextInt();
while (testcase-- > 0) {
int sizeOfArray = sc.nextInt();
int[] arr = new int[sizeOfArray];
for (int i = 0; i < sizeOfArray; i++) {
arr[i] = sc.nextInt();
}
int max1, max2, max3;
max1 = 0;
max2 = 0;
max3 = 0;
for (int i = 0; i < sizeOfArray; i++) {
if (arr[i] > max1) {
max3 = max2;
max2 = max1;
max1 = arr[i];
}
else if (arr[i] > max2) {
max3 = max2;
max2 = arr[i];
}
else if (arr[i] > max3) {
max3 = arr[i];
}
}
System.out.println(max1 + " " + max2 + " " + max3);
}
}
}