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.
Related
I have successfully compiled this java program (which generates 100 random numbers between 0 and 25, puts them in an array, and sorts them into two different arrays based on whether each is even or odd), although it does not run. I suspect I have made a mistake with one of the while loops, although I don't know for sure. Also, I struggled to get the code in properly formatted in the question, so the tabs are somewhat off, but it is still mostly legible. Here is the .java text:
public class Assignment8
{
public static void main( String [] args )
{
int storage [] = new int[100];
int j = 0;
while ( storage.length < 100 ) {
int testVariable = 0 + (int) (Math.random() * ((25 - 0) + 1));
storage[j] = testVariable;
j++;
}
int oddArray[] = OddNumbers( storage );
int evenArray[] = EvenNumbers( storage );
int currentNumber = 0;
System.out.println( "The odd numbers are: " + "\n" );
while ( currentNumber <= 99 ) {
System.out.println( oddArray[currentNumber] + "\n" );
currentNumber++;
}
System.out.println( "\n" + "The even numbers are: " + "\n" );
currentNumber = 0;
while ( currentNumber <= 99 ) {
System.out.println( evenArray[currentNumber] + "\n" );
currentNumber++;
}
}
public static int[] OddNumbers( int storage[] )
{
int currentNumber = 0;
int currentValue = storage[currentNumber];
int oddArray[] = new int[100];
while ( currentNumber <= 99 ) {
if ( storage[currentNumber] % 2 != 0 ) {
oddArray[currentNumber] = currentValue;
} else {
continue;
}
currentNumber++;
}
return oddArray;
}
public static int[] EvenNumbers( int storage[] )
{
int currentNumber = 0;
int currentValue = storage[currentNumber];
int evenArray[] = new int[100];
while ( currentNumber <= 99 ) {
if ( storage[currentNumber] % 2 == 0 ) {
evenArray[currentNumber] = currentValue;
} else {
continue;
}
currentNumber++;
}
return evenArray;
}
}
storage.length does not change throughout the program's execution, as the array is already allocated. You first while loop is thus wrong, as 100 is not less than 100, it will never execute. Instead, you could use a simple for loop:
for (int j = 0; j < storage.length; ++j) {
int testVariable = 0 + (int) (Math.random() * ((25 - 0) + 1));
storage[j] = testVariable;
}
although it does not run
Yes it does. It's just that the execution can get stuck in the infinite loops in the OddNumbers and EvenNumbers methods.
Take a closer look at this:
while ( currentNumber <= 99 ) {
if ( storage[currentNumber] % 2 != 0 ) {
oddArray[currentNumber] = currentValue;
}
else {
continue;
}
The problem is that when storage[currentNumber] is even,
the program executes the else branch with the continue statement,
and since currentNumber hasn't changed, and so storage[currentNumber] hasn't changed either, it's still even, and the else branch will be executed again, and again, and again, forever. EvenNumber has the same problem too.
Here's a fix for OddNumbers:
public static int[] OddNumbers(int[] storage) {
int[] oddArray = new int[storage.length];
int oddIndex = 0;
for (int num : storage) {
if (num % 2 != 0) {
oddArray[oddIndex++] = num;
}
}
return Arrays.copyOf(oddArray, oddIndex);
}
An extra touch I did in this method is the Arrays.copyOf call,
chopping off the excess elements of the array that would be otherwise 0.
Then when you print the content of this array in main, write like this:
System.out.println("The odd numbers are: " + "\n");
for (int num : oddArray) {
System.out.println(num);
}
Follow the same pattern to fix EvenNumbers.
As #Mureinik pointed out,
the loop in main populating storage is also broken.
And you have several other coding issues,
for example the random number generation is particularly ugly and using an obsolete technique.
The complete improved implementation:
import java.util.Arrays;
import java.util.Random;
public class Assignment8 {
public static void main(String[] args) {
Random random = new Random();
int[] storage = new int[100];
for (int i = 0; i < storage.length; i++) {
storage[i] = random.nextInt(25);
}
System.out.println("The odd numbers are: " + "\n");
int oddArray[] = OddNumbers(storage);
for (int num : oddArray) {
System.out.println(num);
}
System.out.println("\n" + "The even numbers are: " + "\n");
int evenArray[] = EvenNumbers(storage);
for (int num : evenArray) {
System.out.println(num);
}
}
public static int[] OddNumbers(int[] storage) {
int index = 0;
int[] result = new int[storage.length];
for (int num : storage) {
if (num % 2 != 0) {
result[index++] = num;
}
}
return Arrays.copyOf(result, index);
}
public static int[] EvenNumbers(int storage[]) {
int index = 0;
int[] result = new int[storage.length];
for (int num : storage) {
if (num % 2 == 0) {
result[index++] = num;
}
}
return Arrays.copyOf(result, index);
}
}
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);
}
}
}
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.
The problem: http://codeforces.com/contest/581/problem/B
My code is O(n), and I compared my code with others, cannot understand why my code exceeds the time limit in test case 6 (with n = 100,000)? Any idea?
private void solve() throws IOException {
//String s = nextToken();
int n = nextInt();
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = nextInt();
}
int max = -1;
String ans = "";
for (int i = array.length-1; i >=0; i--) {
if (array[i] >= max) {
max = array[i];
ans = 0 + " " + ans;
}
else {
ans = ( max - array[i] +1) + " " + ans ;
}
}
writer.println(ans.substring(0,ans.length()-1));
}
Your code is not O(n); + on a String is O(n) and your code is O(n^2). You'd need to use StringBuilder instead.
Additionally, inserting at the beginning instead of the end is also generally bad, so even StringBuilder won't let you do that efficiently.
You'll need to figure out how to build the answer the other way around.
This is for project euler problem 14.
When a number is even, you're supposed to divide the number by two, but when it is odd you multiply it by three and add one. Eventually it should reach one.
My task is to find the number that takes the largest amount of steps to get to 1.
Here's my code:
int currentNum = 0;
int iterator = 0;
int[] largestChain = new int[]{0,0};
for(int i = 10;i<=1000000;i++)
{
currentNum = i;
iterator = 0;
while(currentNum!=1)
{
iterator++;
if(currentNum%2==0)
{
currentNum/=2;
}
else
{
currentNum = (currentNum*3)+1;
}
}
if(iterator>largestChain[1])
{
largestChain[0] = i;
largestChain[1] = iterator;
}
}
System.out.println("largest iterator:"+largestChain[1]+"for num:"+largestChain[0]);
Can you please help me out by telling me what's slowing it down? (It's taking >30 minutes right now and it still hasn't come up with the answer).
Use long variables instead of int. currentNum goes so high the values wrap around into the negatives!
Once you do that change, your algorithm works just fine. (I tested it)
The reason it take so long is that you are performing this while loop operation on 1 million numbers. The solution to this is to create an algorithm which saves the number of steps dynamically.
int[] steps = new int[1000000];
steps[0] = 0;
steps[1] = 1;
Iterate through the rest of your numbers, adding back to this base case. By the end, many of your paths will be computed, and you will not need a nested loop.
However, if you want to stick to your way:
I'd recommend putting some debug print statements in there to see where it is getting caught up. My guess is that the 1 Million looped while statements are the culprit, but the easiest way to find out is progress check.
try adding System.out.println(i+":"); before the while and System.out.println(" current number: "+currentnum); inside the while.
Should print out something like:
1:
1
2:
2
1
etc.
I modified the code to print the interesting info and how its looping. The loop is crazy.
I would suggest converting currentNum to 'long' and re-run it as that number goes negative (beyond int capacity).
public class TestLoop{
public static void main(String[] args){
int currentNum = 0;
int iterator = 0;
int[] largestChain = new int[]{0,0};
for(int i = 10;i<=1000000;i++)
{
currentNum = i;
iterator = 0;
System.out.println("\nCurrently Running :" + i);
while(currentNum!=1)
{
iterator++;
if(currentNum%2==0)
{
currentNum/=2;
}
else
{
currentNum = (currentNum*3)+1;
}
System.out.print(currentNum + " ");
}
if(iterator>largestChain[1])
{
largestChain[0] = i;
largestChain[1] = iterator;
}
}
System.out.println("\nLargest iterator: "+largestChain[1]+" for num:"+largestChain[0]);
}
}
I ran it on linux and got below answer in 10 mins after I changed the currentNum to 'long'.
Largest iterator: 524 for num:837799
Still there is a flaw in your logic: you are NOT checking if any other number taking the same iterations. E.g. below loop gives two such numbers :
import java.util.ArrayList;
public class TestLoop {
public static void main(String[] args) {
long currentNum;
int iterator;
int[] largestChain = new int[]{0, 0};
ArrayList Nums = new ArrayList();
for (int i = 10; i <= 300; i++) {
currentNum = i;
iterator = 0;
System.out.println("\nCurrently Running :" + i);
while (currentNum != 1) {
iterator++;
if (currentNum % 2 == 0) {
currentNum /= 2;
} else {
currentNum = (currentNum * 3) + 1;
}
System.out.print(currentNum + " ");
}
if (iterator > largestChain[1]) {
largestChain[0] = i;
largestChain[1] = iterator;
Nums.clear();
Nums.add(i);
} else if (iterator == largestChain[1]) {
Nums.add(i);
}
}
System.out.println("\nLargest iterator: " + largestChain[1]);
//+ " for num:" + largestChain[0]);
if (Nums.size() == 1) {
System.out.println("There is only one number with " + largestChain[1] + " iterations:" + largestChain[0]);
} else {
System.out.print("Below numbers took " + largestChain[1] + " iterations:");
for (int i = 0; i < Nums.size(); i++) {
System.out.print(" " + Nums.get(i));
}
}
}
}