array/data set constructor questions - java

I'm creating a program which takes a user's info and outputs the min, max, average, sum, and counts how many values were in it. I'm really struggling to figure out how to create default constructor of 100 items and the array size which the user is supposed to define.
Create a new DataSet object. The client creating the object specifies the maximum number
of items that can be added to the set. (Write a constructor with one int parameter.)
Also write a default constructor which creates a DataSet capable of handling 100 items.
Add an integer data item to a DataSet. If the maximum number of items have already been added to the set, the item is simply ignored.
Here is my code
import javax.swing.*;
import java.util.*;
public class DataSet {
private int count; // Number of numbers that have been entered.
private double sum; // The sum of all the items that have been entered.
private double min;
private double max;
//Adds numbers to dataset.
public void addDatum(double num) {
count++;
sum += num;
if (count == 1){
min = num;
max = num;
} else if (num < min){
min = num;
} else if (num > max){
max = num;
}
}
public boolean isEmpty()
{
if(count == 0)
{
return true;
}
else
{
return false;
}
}
//Return number of items entered into the dataset.
public int getCount() {
return count;
}
//Return the sum of all the numbers that have been entered.
public double getSum() {
return sum;
}
//Return the average of all the numbers that have been entered.
public double getAvg() {
return sum / count;
}
//return Maximum value of data entered.
public double getMax(){
return max;
}
//return Minimum value of data entered.
public double getMin(){
return min;
}
public static void main (String[] args){
Scanner scanner = new Scanner(System.in);
DataSet calc = new DataSet();
double nextnumber = 0;
while (true){
System.out.print("Enter the next number(0 to exit): ");
nextnumber = scanner.nextDouble();
if (nextnumber == 0)
break;
calc.addDatum(nextnumber);
}
System.out.println("Min = "+calc.getMin());
System.out.println("Max = "+calc.getMax());
System.out.println("Mean = "+calc.getAvg());
System.out.println("Count = "+calc.getCount());
System.out.println("Sum = "+calc.getSum());
}
} //end class DataSet

The syntax for declaring an array is type[] name; (there are variants, but this is the most common)
So an int array is declared as thus:
int[] someIntegers;
Creating a new array can be done several ways. The normal way is to create an empty array with all elements initialised to their default value (zero or false for primitive datatypes, and null for object arrays). The syntax is:
someIntegers = new int[4]; // ie. [0, 0, 0, 0]
// or
int n = ...; // intitalise n some how
someIntegers = new int[n];
// this way we can get different length arrays at runtime

You have to add a variable to hold the max amount of numbers.
int max = 0;
Then you would need the two constructors:
Dataset() {
max = 100;
}
Dataset(int max) {
this.max = max;
}
Then when you get the input, you have to check if you have reached the number limit before you do anything.
System.out.print("Enter the next number(0 to exit): ");
nextnumber = scanner.nextDouble();
if (count < max) {
if (nextnumber == 0) {
break;
}
calc.addDatum(nextnumber);
}

Your code above does not contain any constructors, so only the default DataSet() constructor is available. In your DataSet class, you need to define both constructors to meet your requirements. In addition you will need to create a collection type (ie an array of ints) for storing the numbers added to the dataset (this seems to be part of your requirements). With the code below, when you create an instance of the DataSet class in your main method, you can create it with the default 100 elements by saying
DataSet myDataSet = new DataSet();
or you can create it with a user specified number of elements like
DataSet myDataSet = new DataSet(30); //for thirty elements in the array
public class DataSet {
int[] myArray;
public DataSet() //Zero parameters constructor
{
//initialize your array to 100 elements here
myArray = new int[100]; //the array can hold 100 elements
}
public DataSet(int max) //One parameter constructor
{
//initialize your array to 'max' elements here
myArray = new int[max]; //the array can hold max number of elements
}
public void AddNum(int num)
{
//logic to add number to the array here :P
}
}

Related

How to swapplaces of largest and smallest value

I am new at learning Java and I have the following assignment:
Write a program which reads three integers a, b and c from the
keyboard and swaps the places of the largest and smallest among the
three values.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Program to find the largest and smalles value");
System.out.println("Please insert first number:");
int first = scanner.nextInt();
System.out.println("Please insert second number:");
int second = scanner.nextInt();
System.out.println("Please insert:");
int third = scanner.nextInt();
int largest = largest(first, second, third);
int smallest = smallest(first, second, third);
System.out.printf("The biggest value among %d, %d, и %d is : %d %n", first, second, third, largest);
System.out.printf("The smallest value among %d, %d, и %d is : %d %n", first, second, third, smallest);
scanner.close();
}
public static int largest(int first, int second, int third) {
int max = first;
if (second > max) {
max = second; }
if (third > max) {
max = third; }
return max; }
public static int smallest(int first, int second, int third) {
int min = first;
if (second < min) {
min = second; }
if (third < min) {
min = third; }
return min; }
I am not sure what "swap places" mean in this contents, but this is how you swap values (in general)
int smallest = 1;
int largest = 5;
int temp = 0;
temp = largest; // save one number to a temporary variable
largest = smaller; // override the variable you just saved
smaller = temp; // place the "temp" variable value into the second variable
If you were to print out smallest and largest, you'll find that their values are now swapped (largest will be 1 and smallest will be 5).
You don't need to swap anything. Here is how it works.
set a value min to the largest possible value.
set a value max to the smallest possible value.
Now for all your values, simply compare current min to that value and current max to that value and replace them as necessary.
When done, min and max should have their respective values.
Then, if you really want to swap them you can apply the technique that #hfontanez suggested.
The assignment does not ask you to find the largest and smallest values - it states that you should swap the position of the largest and smallest values. This implies that there is an ordering of these values. This is typically modeled as an array. So it sounds like you should be reading the three values into an array. Move your input code into a method with the return type int[]. After reading the input you put them in an array and return.
public static int[] getInputs() {
... read the inputs into first, second, third ...
int[] values = {first, second, third};
return values;
}
Once you have the array of values you need to identify the index of the largest values and the smallest value. You then swap the values at those positions. This is normally done with the help of a temporary variable to hold one of those values.
public static void swapPositionOfLargestAndSmallestValues(int[] values) {
int smallestIndex = findIndexOfSmallestValue(values);
int largestIndex = findIndexOfLargestValue(values);
int temp = values[smallestIndex];
values[smallestIndex] = values[largestIndex];
values[largestIndex = temp;
}
You will need to implement the methods that find the indexes of the largest and smallest values. Then your main looks something like this, where printValues(int[]) is a method that outputs the elements of the array in some fashion.
public static void main(String[] args) {
int[] values = getInputs();
printValues(values);
swapPositionOfLargestAndSmallestValues(values);
printValues(values);
}

How to remove value, determine minimum of remaining values

I need to determine the minimum value after removing the first value.
For instance is these are the numbers 0.5 70 80 90 10
I need to remove 0.5, the determine the minimum value in the remaining numbers. calweightAvg is my focus ...
The final output should be “The weighted average of the numbers is 40, when using the data 0.5 70 80 90 10, where 0.5 is the weight, and the average is computed after dropping the lowest of the rest of the values.”
EDIT: Everything seems to be working, EXCEPT during the final out put. "The weighted average of the numbers is 40.0, when using the data 70.0, 80.0, 90.0, 10.0, where 70.0 (should be 0.5) is the weight, and the average is computed after dropping the lowest of the rest of the values."
So the math is right, the output is not.
EDIT: While using a class static double weight=0.5;to establish the weight, if the user were to change the values in the input file, that would not work. How can I change the class?
/*
*
*/
package calcweightedavg;
import java.util.Scanner;
import java.util.ArrayList;
import java.io.File;
import java.io.PrintWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
public class CalcWeightedAvg {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
//System.out.println(System.getProperty("user.dir"));
ArrayList<Double> inputValues = getData(); // User entered integers.
double weightedAvg = calcWeightedAvg(inputValues); // User entered weight.
printResults(inputValues, weightedAvg); //Weighted average of integers.
}
public class CalcWeightedAvg {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
//System.out.println(System.getProperty("user.dir"));
ArrayList<Double> inputValues = getData(); // User entered integers.
double weightedAvg = calcWeightedAvg(inputValues); // User entered weight.
printResults(inputValues, weightedAvg); //Weighted average of integers.
}
public static ArrayList<Double> getData() throws FileNotFoundException {
// Get input file name.
Scanner console = new Scanner(System.in);
System.out.print("Input File: ");
String inputFileName = console.next();
File inputFile = new File(inputFileName);
//
Scanner in = new Scanner(inputFile);
String inputString = in.nextLine();
//
String[] strArray = inputString.split("\\s+"); //LEFT OFF HERE
// Create arraylist with integers.
ArrayList<Double> doubleArrayList = new ArrayList<>();
for (String strElement : strArray) {
doubleArrayList.add(Double.parseDouble(strElement));
}
in.close();
return doubleArrayList;
}
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
Double weight = inputValues.get(0);
inputValues.remove(0);
//Sum and find min.
double min = Double.MAX_VALUE;
double sum = 0;
for (Double d : inputValues) {
if (d < min) min = d;
sum += d;
}
// Calculate weighted average.
return (sum-min)/(inputValues.size()-1) * weight;
}
public static void printResults(ArrayList<Double> inputValues, double weightedAvg) throws IOException {
Scanner console = new Scanner(System.in);
System.out.print("Output File: ");
String outputFileName = console.next();
PrintWriter out = new PrintWriter(outputFileName);
System.out.println("Your output is in the file " + outputFileName);
out.print("The weighted average of the numbers is " + weightedAvg + ", ");
out.print("when using the data ");
for (int i=0; i<inputValues.size(); i++) {
out.print(inputValues.get(i) + ", ");
}
out.print("\n where " + inputValues.get(0) + " is the weight, ");
out.print("and the average is computed after dropping the lowest of the rest of the values.\n");
out.close();
}
}
to do this task in a complexity of O(n) isn't a hard task.
you can use ArrayList's .get(0) to Save weight in a temp variable, then use .remove(0) function which removes the first value (in this case 0.5)
then you should use a For Each loop for (Double d : list) to sum AND find the minimal value
afterwards subtract the minimum value from the sum. and apply weight to the sum (in this case you'll end up with 240*0.5 = 120; 120\3 = 40;
finally, you can use ArrayList's .size()-1 function to determine the divisor.
The problem in your code:
in your implementation you've removed the weight item from list. then multiplied by the first item in the list even though it's no longer the weight:
return (sum-min)/(inputValues.size()-1) * inputValues.get(0);
your calculation than was: ((70+80+90+10)-10)/(4-1) * (70) = 5600
if(inputValues.size() <= 1){
inputValues.remove(0);
}
this size safeguard will not remove weight from the list. perhaps you've meant to use >=1
even if that was your intention this will not result in a correct computation of your algorithm in the edge cases where size==0\1\2 I would recommend that you re-think this.
the full steps that need to be taken in abstract code:
ArrayList<Double> list = new ArrayList();
// get and remove weight
Double weight = list.get(0);
list.remove(0);
// sum and find min
double min=Double.MAX_VALUE;
double sum=0;
for (Double d : list) {
if (d<min) min = d;
sum+=d;
}
// subtract min value from sum
sum-=min;
// apply weight
sum*=weight;
// calc weighted avg
double avg = sum/list.size()-1;
// viola!
do take notice that you can now safely add weight back into the array list after its use via ArrayList's .add(int index, T value) function. also, the code is very abstract and safeguards regarding size should be implemented.
Regarding your Edit:
it appears you're outputting the wrong variable.
out.print("\n where " + inputValues.get(0) + " is the weight, ");
the weight variable was already removed from the list at this stage, so the first item in the list is indeed 70. either add back the weight variable into the list after you've computed the result or save it in a class variable and input it directly.
following are the implementation of both solutions. you should only use one of them not both.
1) add weight back into list solution:
change this function to add weight back to list:
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
Double weight = inputValues.get(0);
inputValues.remove(0);
//Sum and find min.
double min = Double.MAX_VALUE;
double sum = 0;
for (Double d : inputValues) {
if (d < min) min = d;
sum += d;
}
// Calculate weighted average.
double returnVal = (sum-min)/(inputValues.size()-1) * weight;
// add weight back to list
inputValues.add(0,weight);
return returnVal;
}
2) class variable solution:
change for class:
public class CalcWeightedAvg {
static double weight=0;
//...
}
change for function:
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
weight = inputValues.get(0); // changed to class variable
//...
}
change for output:
out.print("\n where " + weight + " is the weight, ");
Since you're using an ArrayList, this should be a piece of cake.
To remove a value from an ArrayList, just find the index of the value and call
myList.remove(index);
If 0.5 is the first element in the list, remove it with
inputValues.remove(0);
If you want to find the minimum value in an ArrayList of doubles, just use this algorithm to find both the minimum value and its index:
double minVal = Double.MAX_VALUE;
int minIndex = -1;
for(int i = 0; i < myList.size(); i++) {
if(myList.get(i) < minVal) {
minVal = myList.get(i);
minIndex = i;
}
}
Hope this helps!
If you want to remove the first element from ArrayList and calculate the minimum in the remaining you should do:
if(inputValues.size() <= 1) //no point in calculation of one element
return;
inputValues.remove(0);
double min = inputValues.get(0);
for (int i = 1; i < inputValues.size(); i++) {
if (inputValues.get(i) < min)
min = inputValues.get(i);
}
I am a little unclear about your goal here. If you are required to make frequent calls to check the minimum value, a min heap would be a very good choice.
A min heap has the property that it offers constant time access to the minimum value. This [implementation] uses an ArrayList. So, you can add to the ArrayList using the add() method, and minValue() gives constant time access to the minimum value of the list since it ensures that the minimum value is always at index 0. The list is modified accordingly when the least value is removed, or a new value is added (called heapify).
I am not adding any code here since the link should make that part clear. If you would like some clarification, I would be more than glad to be of help.
Edit.
public class HelloWorld {
private static ArrayList<Double> values;
private static Double sum = 0.0D;
/**
* Identifies the minimum value stored in the heap
* #return the minimum value
*/
public static Double minValue() {
if (values.size() == 0) {
throw new NoSuchElementException();
}
return values.get(0);
}
/**
* Adds a new value to the heap.
* #param newValue the value to be added
*/
public static void add(Double newValue) {
values.add(newValue);
int pos = values.size()-1;
while (pos > 0) {
if (newValue.compareTo(values.get((pos-1)/2)) < 0) {
values.set(pos, values.get((pos-1)/2));
pos = (pos-1)/2;
}
else {
break;
}
}
values.set(pos, newValue);
// update global sum
sum += newValue;
}
/**
* Removes the minimum value from the heap.
*/
public static void remove() {
Double newValue = values.remove(values.size()-1);
int pos = 0;
if (values.size() > 0) {
while (2*pos+1 < values.size()) {
int minChild = 2*pos+1;
if (2*pos+2 < values.size() &&
values.get(2*pos+2).compareTo(values.get(2*pos+1)) < 0) {
minChild = 2*pos+2;
}
if (newValue.compareTo(values.get(minChild)) > 0) {
values.set(pos, values.get(minChild));
pos = minChild;
}
else {
break;
}
}
values.set(pos, newValue);
}
// update global sum
sum -= newValue;
}
/**
* NEEDS EDIT Computes the average of the list, leaving out the minimum value.
* #param newValue the value to be added
*/
public static double calcWeightedAvg() {
double minValue = minValue();
// the running total of the sum took this into account
// so, we have to remove this from the sum to get the effective sum
double effectiveSum = (sum - minValue);
return effectiveSum * minValue;
}
public static void main(String []args) {
values = new ArrayList<Double>();
// add values to the arraylist -> order is intentionally ruined
double[] arr = new double[]{10,70,90,80,0.5};
for(double val: arr)
add(val);
System.out.println("Present minimum in the list: " + minValue()); // 0.5
System.out.println("CalcWeightedAvg: " + calcWeightedAvg()); // 125.0
}
}

Java Average Program

Write a class called Average that can be used to calculate average of several integers. It should contain the following methods:
A method that accepts two integer parameters and returns their average.
A method that accepts three integer parameters and returns their average.
A method that accepts two integer parameters that represent a range.
Issue an error message and return zero if the second parameter is less than the first one. Otherwise, the method should return the average of the integers in that range (inclusive).
Implement the class and write a program to test its methods and submit your source code (.java files).
I am stuck on part three, I don't even really understand the stipulation. Will I be using a floating point / double? Here is the program I have thus far:
import java.util.Scanner;
public class Average {
public static void main(String[] args) {
int numb1, numb2, numb3, userInput;
System.out.println("Enter '2' if you wish to average two numbers enter '3' if you wish to average 3.");
Scanner keyboard = new Scanner(System.in);
userInput = keyboard.nextInt();
if (userInput == 2){
System.out.println("Enter two numbers you'd like to be averaged.");
numb1 = keyboard.nextInt();
numb2 = keyboard.nextInt();
Average ave = new Average();
System.out.println("The average is: " + ave.average(numb1, numb2));
System.exit(1);
}
if(userInput == 3){
System.out.println("Enter three numbers you'd like to be averaged.");
numb1 = keyboard.nextInt();
numb2 = keyboard.nextInt();
numb3 = keyboard.nextInt();
Average ave = new Average();
System.out.println("The average is: " + ave.average(numb1, numb2, numb3));
System.exit(1);
}
}
public static int average (int num1, int num2) {
return (num1 + num2) / 2;
}
public static int average (int numb1, int numb2, int numb3){
return (numb1 + numb2 + numb3) / 3;
}
}
Please don't re-ask the same question as you just asked here: http://stackoverflow.com/questions/19507108/java-averaging-program
Rather update your other post to reflect your new code / questions.
Now onto your question:
A method that accepts two integer parameters that represent a range. Issue an error message and return zero if the second parameter is less than the first one. Otherwise, the method should return the average of the integers in that range (inclusive). Implement the class and write a program to test its methods and submit your source code (.java files).
Lets start by declaring our method and we'll declare it as static to conform to your program (since you're not creating your own objects). Then we want to check if the parameters follow the assignment instructions and return values accordingly.
public static int getRange(int firstValue, int secondValue)
{
int range;
if (firstValue > secondValue)
range = firstValue - secondValue;
else
{
range = 0;
System.out.println("Error!");
}
return range;
}
**To promote your understanding it's up to you to find the average of the integers in the range!
Not really here to do your homework, but since I'm already here, the range is the difference between the largest and smallest number.
public int returnRange(int first, int second) {
if(first > second)
return first-second;
else
return second-first;
}
To make things easier though...
public double returnAverage(int...numbers) {
for(int i = 0; i < numbers.length(); i++) {
total += numbers;
}
return total/numbers.length();
}
public int returnRange(int...numbers) {
int holder = 0;
int highest;
int lowest;
for(int i = 0; i < numbers.length(); i++) {
if(numbers[i] > holder) {
holder = numbers[i];
}
highest = holder;
for(int i = 0; i < numbers.length(); i++) {
if(numbers[i] < holder) {
holder = numbers[i];
}
}
lowest = holder;
return highest-lowest;
}
Last 2 methods are un-tested, but from experience, should work fine. These methods have arrays for the parameters, so you can do as many numbers as you'd like.
In your main method check for -1 and return error when first value is greater than second
public double avgRange(int a, int b){
if(a>b){
return -1;
}
else{
double total=0;
for(int x=a; x<=b; x++){
total = total + x;
}
return total/(b-a+1);
}
}
the method should return the average of the integers in that range (inclusive).
You're asked to return the average of all integers in the range bounded by the two parameters.
For example, if parameters were 5 and 10, the method should return the average of 5, 6, 7, 8, 9, and 10, which is 7.5. (5 and 10 are included because the question says the range should be "inclusive".)
To find the average, use a for loop to sum each integer in the range, then divide by the number of integers.
Will I be using a floating point / double?
The return value should be a float or double, since the average isn't always a whole number.

Find Max Number(s) in an ArrayList (Possibility of More Than One Max Value)

I would like to find the index/indices that hold the maximum value in an ArrayList. I want to preserve the order that the numbers are in (in other words no sorting) because I want to keep track of what index had what value. The values are from a random number generator and there is the possibility of having two (or more) indices sharing the same maximum value.
An example ArrayList:
12, 78, 45, 78
0,1,2,3 <- indices
(So indices, 1 and 3 contain the values that have the max values. I want to maintain the fact that indices 1 and 3 have the value 78. I do not want to just create a new ArrayList and have indices 0 and 1 of the new ArrayList have the values 78)
Therefore, I want to find all of the indices that have the maximum values because I will be doing something with them to "break" the tie if there is more than one index. So how can I find the indices that contain the maximum value and maintain the index-to-value relationship?
I have written the following methods:
public static ArrayList<Integer> maxIndices(ArrayList<Integer> numArrayList) {
// ???
return numArrayList;
}
public static void removeElement(ArrayList<Integer> numArrayList, int index) {
numArrayList.remove(index);
}
public static int getMaxValue(ArrayList<Integer> numArrayList) {
int maxValue = Collections.max(numArrayList);
return maxValue;
}
public static int getIndexOfMaxValue(ArrayList<Integer> numArrayList, int maxVal) {
int index = numArrayList.indexOf(maxVal);
return index;
}
public static ArrayList<Integer> maxIndices(ArrayList<Integer> list) {
List<Integer> indices = new ArrayList<Integer>();
int max = getMaxValue(list);
for (int i = 0; i < list.size(); i++) {
if(list.get(i) == max) {
indices.add(list.get(i));
}
}
return indices;
}
O(n) solution:
public static List<Integer> maxIndices(List<Integer> l) {
List<Integer> result = new ArrayList<Integer>();
Integer candidate = l.get(0);
result.add(0);
for (int i = 1; i < l.size(); i++) {
if (l.get(i).compareTo(candidate) > 0) {
candidate = l.get(i);
result.clear();
result.add(i);
} else if (l.get(i).compareTo(candidate) == 0) {
result.add(i);
}
}
return result;
}

Complexity and Efficiency in Algorithm for: a[j]-a[i] i>=j

I'm looking to make this much quicker. I've contemplated using a tree, but I'm not sure if that would actually help much.
I feel like the problem is for most cases you don't need to calculate all the possible maximums only a hand full, but I'm not sure where to draw the line
Thanks so much for the input,
Jasper
public class SpecialMax {
//initialized to the lowest possible value of j;
public static int jdex = 0;
//initialized to the highest possible value of i;
public static int idex;
//will hold possible maximums
public static Stack<Integer> possibleMaxs = new Stack<Integer> ();
public static int calculate (int[] a){
if (isPositive(a)){
int size = a.length;
int counterJ;
counterJ = size-1;
//find and return an ordered version of a
int [] ordered = orderBySize (a);
while (counterJ>0){
/* The first time this function is called, the Jvalue will be
* the largest it can be, similarly, the Ivalue that is found
* is the smallest
*/
int jVal = ordered[counterJ];
int iVal = test (a, jVal);
possibleMaxs.push(jVal-iVal);
counterJ--;
}
int answer = possibleMaxs.pop();
while (!possibleMaxs.empty()){
if (answer<possibleMaxs.peek()){
answer = possibleMaxs.pop();
} else {
possibleMaxs.pop();
}
}
System.out.println("The maximum of a[j]-a[i] with j>=i is: ");
return answer;
} else {
System.out.println ("Invalid input, array must be positive");
return 0; //error
}
}
//Check to make sure the array contains positive numbers
public static boolean isPositive(int[] a){
boolean positive = true;
int size = a.length;
for (int i=0; i<size; i++){
if (a[i]<0){
positive = false;
break;
}
}
return positive;
}
public static int[] orderBySize (int[] a){
//orders the array into ascending order
int [] answer = a.clone();
Arrays.sort(answer);
return answer;
}
/*Test returns an Ival to match the input Jval it accounts for
* the fact that jdex<idex.
*/
public static int test (int[] a, int jVal){
int size = a.length;
//initialized to highest possible value
int tempMin = jVal;
//keeps a running tally
Stack<Integer> mIndices = new Stack<Integer> ();
//finds the index of the jVal being tested
for (int i=0; i<size; i++) {
if (jVal==a[i]){
//finds the highest index for instance
if (jdex<i){
jdex = i;
}
}
}
//look for the optimal minimal below jdex;
for (int i=0; i<jdex; i++){
if (a[i]<tempMin){
tempMin = a[i];
mIndices.push(i);
}
}
//returns the index of the last min
if (!mIndices.empty()){
idex = mIndices.pop();
}
return tempMin;
}
}
It can be done in linear time and linear memory. The idea is: find the minimum over each suffix of the array and maximum over each prefix, then find the point where the difference between the two is the highest. You'll also have to store the index on which the maximum/minimum for each prefix is reached if you need the indices, rather than just the difference value.
Pre-sorting a[] makes the procedure complicated and impairs performance. It is not necessary, so we leave a[] unsorted.
Then (EDITED, because I had read j>=i in the body of your code, rather than i>=j in the problem description/title, which I now assume is what is required (I didn't go over your coding details); The two varieties can easily be derived from each other anyway.)
// initialize result(indices)
int iFound = 0;
int jFound = 0;
// initialize a candidate that MAY replace jFound
int jAlternative = -1; // -1 signals: no candidate currently available
// process the (remaining) elements of the array - skip #0: we've already handled that one at the initialization
for (int i=1; i<size; i++)
{
// if we have an alternative, see if that combines with the current element to a higher "max".
if ((jAlternative != -1) && (a[jAlternative]-a[i] > a[jFound]-a[iFound]))
{
jFound = jAlternative;
iFound = i;
jAlternative = -1;
}
else if (a[i] < a[iFound]) // then we can set a[iFound] lower, thereby increasing "max"
{
iFound = i;
}
else if (a[i] > a[jFound])
{ // we cannot directly replace jFound, because of the condition iFound>=jFound,
// but when we later may find a lower a[i], then it can jump in:
// set it as a waiting candidate (replacing an existing one if the new one is more promising).
if ((jAlternative = -1) || (a[i] > a[jAlternative]))
{
jAlternative = i;
}
}
}
double result = a[jFound] - a[iFound];

Categories

Resources