Maximum Single Sell Profit algorithm (Java) - java

I am working on creating an algorithm to maximize profit from a .txt file where each line is the price of a certain stock on a day (Starting with day 0).
The output of my program should be "[day you should buy the stock, day you should sell the stock, profit made]".
For example:
Text file:
12, 45, 3, 15, 60, 23, 4
The output should be [2, 4, 57].
My code returns the actual VALUES and not the index of those values.
My output: [3, 60, 57].
I am a beginner, and I cannot seem to find out what to do to produce the correct output! Help would be very much appreciated!
(Trade is a separate class that returns (in, out, profit)).
[EDIT]: I am supposed to do this recursively, and make sure the the overall time cost of the solution is O(n log n)!
Here is my code:
(Apologies if it is messy/things are in it that aren't needed! :) )
import java.util.*;
import java.lang.Math;
import java.io.*;
public class Test_BestTrading
{
public static void main(String[] args) throws Exception
{
//open file
String fileName = args[0];
File inFile = new File(fileName);
Scanner fin = new Scanner(inFile);
int count = 0;
//find out length of array
while(fin.hasNext())
{
fin.nextLine();
count++;
}
fin.close();
int[]p = new int[count];
fin = new Scanner(inFile);
//read numbers into array
for(int i =0; i < count; i++)
p[i] = Integer.parseInt(fin.nextLine());
Trade trade = BestTrade(p, 0, p.length-1);
System.out.println("[" + trade.in + ", " + trade.out + ", " + trade.profit + "]");
}
public static Trade BestTrade(int[] p, int in, int out)
{
if (p.length <= 1)
return new Trade(in, out, out-in);
//Create two arrays - one is left half of "p", one is right half of "p".
int[] left = Arrays.copyOfRange(p, 0, p.length/2);
int[] right = Arrays.copyOfRange(p, p.length/2, p.length);
// Find best values for buying and selling only in left array or only in right array
Trade best_left = BestTrade(left, 0, left.length-1);
Trade best_right = BestTrade(right, 0, right.length-1);
// Compute the best profit for buying in the left and selling in the right.
Trade best_both = new Trade(min(left), max(right), max(right) - min(left));
if (best_left.profit > best_right.profit && best_left.profit > best_both.profit)
return best_left;
else if (best_right.profit > best_left.profit && best_right.profit > best_both.profit)
return best_right;
else
return best_both;
}
public static int max(int[] A)
{
int max = 0;
for(int i=0; i < A.length; i++)
{
if(A[i] > max)
max = A[i];
}
return max;
}
public static int min(int[] A)
{
int min = 100000;
for(int i=0; i < A.length; i++)
{
if(A[i] < min)
min = A[i];
}
return min;
}
}

Once you have your array of numbers, you could simply run a for loop to detect the lowest value and the greatest value as well as the indices of each number.
int greatestDifference = 0;
int indexLowest = 0;
int indexHighest = 0;
for(int i = 0; i < values.length; i++)
for(int j = i + 1; j < values.length; j++)
if(values[i] - values[j] < greatestDifference){
greatestDifference = values[i] - values[j];
indexLowest = i;
indexHighest = j;
}
System.out.println("Buy value is " + values[indexLowest] + " on day " + (indexLowest + 1) + ".");
System.out.println("Sell value is " + values[indexHighest] + " on day " + (indexHighest + 1) + ".");
System.out.println("Net gain is " + Math.abs(greatestDifference));

Check it -
public class BuySellProfit {
public static void main(String[] args) {
int[] a = { 12, 45, 3, 15, 60, 23, 4 };
int min = a[0];
int max = a[0];
int minIndex=0;
int maxIndex=0;
for (int count = 0; count < a.length; count++) {
if (a[count] > max) {
max = a[count];
maxIndex=count;
}
}
System.out.println("Max = " + max);
for (int count = 0; count < a.length; count++) {
if (a[count] < min) {
min = a[count];
minIndex=count;
}
}
System.out.println("min=" + min);
profit(a, minIndex, maxIndex);
}
private static void profit(int a[], int i, int j) {
int profit = a[j] - a[i];
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(i);
list.add(j);
list.add(profit);
System.out.println(list);
}
}
Output :-
Max = 60
min=3
[2, 4, 57]
You just return the index number instead of Value,
It will work.. BTW your code is OK.

import java.util.Scanner;
public class Example4 {
public static void main(String[] args) {
//System.out.println("input the valuer:");
Scanner x =new Scanner(System.in);
for( int i=1;i<13;i++){
System.out.println("Profit for month" +i);
System.out.println("input the valuer :");
float valuer1 =x.nextFloat();
float result=0;
result+=valuer1;
System.out.println("Total profits for months:"+result);
}
}
}

Related

Issue with java array not identifying maximum number

This code is entirely completed. I'm having an issue where the maximum number is being selected and printed as the number right before the maximum. I can't seem to figure out how to make the program print out the actual maximum. For clarification, I'm not looking for an answer to my homework as the code is 99.9% done, I just need assistance on this one issue.
Here's the code:
package Zivkovic7;
import java.util.Arrays;
import java.util.Random;
public class Test {
private static Random rand = new Random();
public static void main(String[] args) {
int[] randomEight = new int[8];
for (int i = 0; i < 8; i++) {
//Get a random number between 50 and 100
randomEight[i] = rand.nextInt(51) + 50;
}
int[] extremeValues = sortArray(randomEight);
System.out.println("The lowest element is " + extremeValues[0]);
System.out.println("The highest element is " + extremeValues[1]);
int sum = 0;
int oddCount = 0;
int evenCount = 0;
System.out.println("\nHere is the array: ");
for (int i = 0; i < randomEight.length; i++) {
System.out.print(randomEight[i] + " ");
if (randomEight[i] % 2 == 0) {
evenCount++;
} else {
oddCount++;
}
sum += randomEight[i];
}
System.out.println("\nEvens: " + evenCount);
System.out.println("\nOdds: " + oddCount);
System.out.println("\nSum of all elements : " + sum);
}
public static int[] sortArray(int[] input) {
int extremeVal[] = new int[2];
extremeVal[0] = input[0]; /* Minimum */
extremeVal[1] = input[1]; /* Maximum */
/*
* Bubble Sort Algorithm
* */
int n = input.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (input[j] > input[j + 1]) {
int temp = input[j];
input[j] = input[j + 1];
input[j + 1] = temp;
}
}
/* Finding minimum */
if (extremeVal[0] > input[i]) {
extremeVal[0] = input[i];
}
/* Finding maximum */
if (extremeVal[1] < input[i]) {
extremeVal[1] = input[i];
}
}
return extremeVal;
}
}
Sorry if anything looks wonky, this is my first time posting to stack overflow. Also, if any more information is needed, i can promptly provide.
You don't need to capture the min and max at each iteration. Just wait the end of sorting.
You failed because the maximum was always the n-2 (the second maximum)
This might help. Change the end of your code with these lines.
// /* Finding minimum */
// if (extremeVal[0] > input[i]) {
// extremeVal[0] = input[i];
// }
// /* Finding maximum */
// if (extremeVal[1] < input[i]) {
// extremeVal[1] = input[i];
// }
}
extremeVal[0] = input[0];
extremeVal[1] = input[n-1];
return extremeVal;

Finding largest gap between consecutive numbers in array Java

I'm currently working on a homework assignment and the final task of the assignment is to write a method to find the largest gap between consecutive numbers in an unsorted array. Example: if the array had the values {1,2,3,4,5,20} the gap would be 15. Currently the array is holding 20 values generated at random.
I'm totally lost for how I would make this happen. Initially my idea for how to solve this would be using a for loop which runs through each value of the array with another loop inside to check if the current value is equal to the previous value plus 1. If it is then store that number as the minimum in the range. Another problem I ran into was that I have no idea how to store a second number without overwriting both numbers in the range. Basically nothing i've tried is working and could really use some help or at least a nudge in the right direction.
What the method does right now is only store the value for "a" after it finds a number that isn't consecutive in the array.
Here's the code I have so far
import java.util.Arrays;
class Main {
public static void main(String[] args) {
Main m = new Main();
m.runCode();
}
public void runCode()
{
Calculator calc = new Calculator();
calc.makeList(20);
System.out.println("List:");
calc.showList();
System.out.println("Max is: " + calc.max());
System.out.println("Min is: " + calc.min());
System.out.println("Sum is: " + calc.sum());
System.out.println("Ave is: " + calc.average());
System.out.println("There are " + calc.fiftyLess() + " values in the list that are less than 50");
System.out.println("Even numbers: " + calc.Even());
}
}
class Calculator {
int list[] = new int[20];
public void makeList(int listSize)
{
for (int count = 0; count < list.length; count++) {
list[count] = (int) (Math.random() * 100);
}
}
public void showList()
{
for (int count = 0; count < list.length; count++)
{
System.out.print(list[count] + " ");
}
}
public int max()
{
int max = list[0];
for (int count=0; count<list.length; count++){
if (list[count] > max) {
max = list[count];
}
}
return max;
}
public int min()
{
int min = list[0];
for (int count=0; count<list.length; count++){
if (list[count] < min) {
min = list[count];
}
}
return min;
}
public int sum()
{
int sum = 0;
for (int count=0; count<list.length; count++){
sum = sum + list[count];
}
return sum;
}
public double average()
{
int sum = sum();
double average = sum / list.length;
return average;
}
public int fiftyLess()
{
int lessThan = 0;
for (int count =0; count<list.length;count++)
{
if (list[count] < 50)
{
lessThan++;
}
}
return lessThan;
}
public int Even()
{
int isEven = 0;
for (int count = 0; count<list.length;count++)
{
if (list[count] % 2 == 0)
{
isEven++;
}
}
return isEven;
}
public int Gap()
{
int a = 0;
int b = 0;
int gap = math.abs(a - b);
for (int count = 1; count<list.length;count++)
{
if (list[count] != list[count] + 1)
{
a =list[count];
}
}
}
}
By using the java8 stream library you could achieve this in fewer lines of code.
This code segment iterates the range of the array, and subtracts all consecutive numbers, and returns the max difference between them or -1, in case the array is empty.
import java.util.stream.IntStream;
class Main {
public static void main(String[] args) {
int[] list = {1, 2, 3, 4, 5, 20};
int max_difference =
IntStream.range(0, list.length - 1)
.map(i -> Math.abs(list[i + 1] - list[i]))
.max().orElse(-1);
System.out.println(max_difference);
}
}
Alternatively you could do this with a traditional for loop.
class Main {
public static void main(String[] args) {
int[] list = {1, 2, 3, 4, 5, 20};
int max_difference = -1;
int difference;
for (int i = 0; i < list.length - 1; i++) {
difference = Math.abs(list[i + 1] - list[i]);
if(difference > max_difference)
max_difference = difference;
}
System.out.println(max_difference);
}
}
Output for both code segments:
15

Printing an array from lowest to highest without sorting

I want to start off by saying I am not very experienced and I am sorry if this has been answered. I have been trying to find an answer for a while and have not been able to.
I am working on a project where the user inputs numbers into an array. These numbers represent temperatures for different days. The days are obviously the position in the array. I need to find a way to print the temperatures from least to greatest without sorting the array.
So if the user entered [56, 45, 67, 41, 59, 70] that means that it was 56 degrees at position 0 (day 1), 67 degrees at position 2 (day 3). I need to keep the position of the array the same so the days remain with the temps when it prints out.
Edit: I have attached the code I have on my project so far. The HighestOrdered method is the method I dont know what to do or where to start. For the HighestOrdered method as I said above I need to have it print out the temps with the day (the position in the array) and I am not sure how to do that.
This is the code I have so far:
public class Weather {
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] high = new int[30];
int [] low = new int[30];
Init (high);
Init(low);
LoadData(high,low);
Report(high, low);
FindAvg(high,low);
Lowest(high, low);
Highest(high,low);
}
public static void Init(int A[])
{
for(int i = 0; i < A.length; i++)
{
A[i] = 510;
}
}
public static void Report(int[] H, int[] L)
{
System.out.println("Day High Low");
for(int i = 0; i < H.length; i++)
{
System.out.println(i + " " + H[i] + " " + L[i]);
}
}
public static void LoadData(int[] H, int[] L)
{
int day = 0;
while(day < 30)
{
try {
int high = Integer.parseInt(JOptionPane.showInputDialog("please enter the high"));
H[day] = high;
} catch (NumberFormatException e) {
}
try {
int low = Integer.parseInt(JOptionPane.showInputDialog(" Please enter the low"));
L[day] = low;
} catch (NumberFormatException e) {
}
day++;
}
}
public static void FindAvg(int[] H, int[] L){
int sumHigh = 0;
int avgHigh;
int sumLow = 0;
int avgLow;
for(int i : H)
sumHigh += i;
avgHigh = sumHigh/H.length;
for(int i : L)
sumLow += i;
avgLow = sumLow/L.length;
System.out.println("The average for the high is: " + avgHigh);
System.out.println("The average for the low is: " + avgLow);
}
public static void Highest(int[] H, int[] L)
{
int highestHigh = -1000;
int dayHigh = 0;
int highestLow = -1000;
int dayLow = 0;
for(int i = 0; i < H.length; i++)
{
if(H[i] > highestHigh && H[i] != 510)
{
highestHigh = H[i];
dayHigh = i;
}
}
System.out.println("\n" + "The highest high is: " + highestHigh + " degrees." + "\n" +
"This temperature was recorded on day: " + dayHigh);
for(int i = 0; i < L.length; i++)
{
if(L[i] > highestLow && L[i] != 510)
{
highestLow = L[i];
dayLow = i;
}
}
System.out.println("\n" + "The highest low is: " + highestLow + " degrees." + "\n" +
"This temperature was recorded on day: " + dayLow);
}
public static void Lowest(int[] H, int[] L)
{
int lowestHigh = 1000;
int dayHigh = 0;
int lowestLow = 1000;
int dayLow = 0;
for(int i = 0; i < H.length; i++)
{
if(H[i] < lowestHigh)
{
lowestHigh = H[i];
dayHigh = i;
}
}
System.out.println("\n" + "The lowest high is: " + lowestHigh + " degrees." + "\n" +
"This temperature was recorded on day: " + dayHigh);
for(int i = 0; i < L.length; i++)
{
if(L[i] < lowestLow)
{
lowestLow = L[i];
dayLow = i;
}
}
System.out.println("\n" + "The lowest low is: " + lowestLow + " degrees." + "\n" +
"This temperature was recorded on day: " + dayLow);
}
public void HighestOrdered(int[] H)
{
}
}
Here's a start.
From your array, create a sorted Map, say
Map<Integer,Integer> mymap = new TreeMap<Integer,Integer>.
You will use temp for the key and the day for the value. e.g., from your example data,
myMap.put(56,1);
myMap.put(45,2);
(Note - in the real code you'd iterate over the array to put the values.)
Then you can iterate over the keys and values (or the entries) in myMap.
Here is a small example to show how this can be done. Only the auxiliary index array is sorted, the original temp array is not changed.
public static void main(String[] args) {
final int [] temp = {56, 45, 67, 41, 59, 70};
Integer [] index = new Integer[temp.length];
for (int i = 0; i < index.length; i++) {
index[i] = i;
}
Arrays.sort(index, new Comparator<Integer>() {
#Override
public int compare(Integer a, Integer b) {
return temp[a] - temp[b];
}
});
for (Integer i : index) {
System.out.printf("temp %d on day %d%n", temp[i], i);
}
}
This gives the output:
temp 41 on day 3
temp 45 on day 1
temp 56 on day 0
temp 59 on day 4
temp 67 on day 2
temp 70 on day 5
Instead of your current array, you can create an object array with each object having two elements: the day and the corresponding temperature.
Sort this array by the temperature value and then print it.

Maximum subsequence sum in an array with no 3 consecutive number

I have to find the maximum sum in an array such that no 3 consecutive number together
for eg
3 4 5 1 2
should return me 11. (4+5+2)
I am getting out as 9.
I am using dynamic programming since I want the running time to be O(N)
The idea is s array will store the max sum and s1 array will store the length of input seen to keep track of consecuent numbers
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class ex {
public static int maxSubArraySum(int a[], int size)
{
int s[]= new int[size+1];
s[0]=0;
int s1[]= new int[size+1];
s1[0]=0;
for (i = 1; i <= size; i++)
{
s1[i]= 1+s1[i-1];
if(s1[i]<3) {
int k=Math.max(s[i-1], a[i-1]+s[i-1]);
s[i]=k;
}
else {
s[i]=Math.max(a[i-1], a[i-1]+a[i]);
s1[i]=0;
}
}
return s[s.length-1];
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc= new Scanner(System.in);
int size=sc.nextInt();
int a[]=new int[size];
for(int i=0;i<size;i++) {
a[i]=sc.nextInt();
}
System.out.println(maxSubArraySum(a, a.length));
}
}
I think your code requires a slight tweak, below are the changes you need to make
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class ex
{
public static int maxSubArraySum(int a[], int size)
{
int s[] = new int[size+2];
//they will form your base cases
s[0] = 0;
s[1] = a[0];
s[2] = a[0] + a[1];
for(int i = 2; i < size; i++)
{
s[i+1] = Math.max(a[i] + s[i-1], a[i] + a[i-1] + s[i-2]);
s[i+1] = Math.max(s[i+1], s[i]);
}
return s[size];
}
public static void main(String[] args)
{
Scanner sc= new Scanner(System.in);
int size=sc.nextInt();
int a[]=new int[size];
for(int i=0;i<size;i++)
{
a[i]=sc.nextInt();
}
System.out.println(maxSubArraySum(a, a.length));
}
}
Hope this helps.
Consider the array starts from index 0...n-1 i.e a[0...n-1],
we create array table[n+1] and table[i] means maximum sum from 1 to i without no three continuous numbers. While computing table[i], we have to choose whether to select i th element or not.
So, three cases are there
Case 1: Since, we can't select three consecutive numbers, but can select two consecutive numbers and skipping third one.
Case 2: select i th element and skip (i-1) th element.
Case 3: If we doesn't select i th element
So, based on above discussion c++ code is given below:
int max_sum_no_three_consecutive(int a[], int n)
{
int table[n+1];
table[0] = 0;
table[1] = a[0];
table[2] = a[1];
for (int i = 3; i <= n; i++) table[i] = max_3(table[i-1], table[i-2] + a[i-1], a[i-1] + a[i-2] + table[i-3]);
return table[n];
}
It's an old post but thought of answering the question.
for(int i = 0; i < input.length; i++) {
if(0 == i) {
sum[i] = input[0];
} else if(1 == i) {
sum[i] = input[0] + input[1];
} else if(2 == i){
sum[i] = getMaxOf3(sum[i - 1], sum[i-2] + input[i], input[i] + input[i - 1]);
} else {
sum[i] = getMaxOf3(sum[i - 1], sum[i - 2] + input[i], sum[i - 3] + input[i] + input[i - 1]);
}
}
int getMaxOf3(int x,
int y,
int z) {
return Math.max(Math.max(x, y), z);
}
Explanation:
Consider the array: {3, 4, 5, 1, 2}
we need to first have some default values for the result array.
sum[0] = array[0];
sum[1] = array[0] + array[1];
sum[2] = maximum of either (arr[0] + arr[1]) or (arr[1] + ar[2]) or (arr[0] + arr[2])
We calculated 3 sums,as we will be using these for furthur sum calculations.
sum[3] = max(sum[2], sum[1] + arr[3], sum[0] + arr[3] + arr[2]);
This reduces to,
sum[i] = max(sum[i - 1], sum[i - 2] + arr[i], sum[i - 3] + arr[i] + arr[i - 1]);

calling arrays from different methods, why java.lang.ArrayIndexOutOfBoundsException?

Question: what is wrong with my arrays, and how do I fix it?
Details:
I initialized the array in the main method, and the values were set in one method. I called the array values in a 2nd method, and everything was fine.
When I tried to call the array in a 3rd method, I got the out of bounds error, even though the size of the array is exactly the same.
I was trying to call the array in order to copy it, and then sort the 2nd array.
thank you
private static WeatherLocation[] WeatherSpots = new WeatherLocation[6];
private static Scanner Input = new Scanner(System.in);
public static void main(String[] args)
{int Count;
for(Count = 0 ; Count < 6; Count++)
WeatherSpots[Count] = new WeatherLocation();
WeatherSpots[0].LocationID = "Tciitcgaitc";
WeatherSpots[1].LocationID = "Redwood Haven";
WeatherSpots[2].LocationID = "Barrier Mountains";
WeatherSpots[3].LocationID = "Nina's Folly";
WeatherSpots[4].LocationID = "Scooly's Hill";
WeatherSpots[5].LocationID = "Twin Cones Park";
SetUp();
String Command = "";
while(!Command.equals("Quit")) {
Menu();
System.out.print("Enter Command: ");
Command = Input.nextLine();
if(Command.equals("Post"))
PostTemperatureInfo();
if(Command.equals("Daily"))
WeeklyReport();
else if (Command.equals("HighLow"))
Sorting();
}
}
public static void PostTemperatureInfo()
{
Scanner LocalInput = new Scanner(System.in);
int K;
int Temp;
//...then get the values for each location...
System.out.println( "Enter the Temperature for each weather station below:\n");
System.out.println( "---------------------------------------------------------------");
for(K = 0 ; K < 6 ; K++) {
System.out.println( "Weather Station: " + WeatherSpots[K].LocationID); //Display the location of the fishing spot...
System.out.print( "Enter Temperature:\t"); //Get the count...
Temp = LocalInput.nextInt();
System.out.println( "---------------------------------------------------------------");
WeatherSpots[K].CatchCount = Temp;
}
System.out.println("");
System.out.println("");
System.out.println("");
}
public static void WeeklyReport()
{
for(K = 0 ; K < 6 ; K++)
{System.out.println( "" + WeatherSpots[K].LocationID +"\t\t" + WeatherSpots[K].CatchCount + "\t\t" + String.format("%.2f", (WeatherSpots[K].CatchCount - 32) * 5 / 9));
}
}
public static void Sorting()
{int K = 0;
for(K = 0 ; K < 6 ; K++);
{int [] copycat = new int[K];
System.arraycopy(WeatherSpots[K].CatchCount, 0, copycat[K], 0, 6);
System.out.println("" + copycat[K]);
Arrays.sort(copycat, 0, K);
System.out.println("Minimum = " + copycat[0]);
System.out.println("Maximum = " + copycat[K -1]);
}
}
}
The problem is that you are allocating an array copycat that is only K integers long, and then you are trying to fit 6 elements into it, even when K == 0. I don't understand your code enough to figure out what the right indexes are, but that's the source of your problem.
Actually, I don't believe that your code as posted will compile. This line from Sorting():
System.arraycopy(WeatherSpots[K].CatchCount, 0, copycat[K], 0, 6);
seems mighty suspicious. The first and third arguments to System.arraycopy are supposed to be arrays, but copycat[K] is an int. Apparently so is WeatherSpots[K].CatchCount.
EDIT:
It seems from your comments and code that the Sorting() routine is just supposed to print the min and max values of WeatherSpots[K].CatchCount. This can be done much more easily than you are doing. Here's one way:
public static void Sorting() {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (WeatherLocation loc : WeatherSpots) {
final int count = loc.CatchCount;
if (count < min) {
min = count;
}
if (count > max) {
max = count;
}
}
System.out.println("Minimum = " + min);
System.out.println("Maximum = " + max);
}
Q: Why not use "array.length" instead of a hard-coded "6"?
Q: I'd really discourage you from using that indentation style, if you can avoid it.
Anyway - this should work (I have not tried it myself):
public static void Sorting() {
for(int K = 0 ; K < WeatherSpots.length ; K++) {
int [] copycat = new int[K];
System.arraycopy(
WeatherSpots[K].CatchCount, 0, copycat[K], 0, WeatherSpots.length);
System.out.println("" + copycat[K]);
Arrays.sort(copycat, 0, K);
System.out.println("Minimum = " + copycat[0]);
System.out.println("Maximum = " + copycat[K -1]);
}
}
The main thing was to get rid of the extraneous ";" after the "for()" loop.

Categories

Resources