I have written a BubbleSort program and it works great, gives me a good output and does its job sufficiently. But I am unable to make the program re-execute after sorting through once. I.e. the program completes a sort of 10000 unique numbers and outputs the time it takes and the amount of steps it took, but doesn't execute again, say for another 999 times after that?
In short, can anyone help me get my program to run through itself 1000 times so I am able to get an average of execution time?
Here is the code:
public class BubbleSort {
public static void main(String[] args) {
int BubArray[] = new int[] { #10000 unique values unsorted# };
System.out.println("Array Before Bubble Sort");
for (int a = 0; a < BubArray.length; a++) {
System.out.print(BubArray[a] + " ");
}
double timeTaken = bubbleSortTimeTaken(BubArray);
int itrs = bubbleSort(BubArray);
System.out.println("");
System.out.println("Array After Bubble Sort");
System.out.println("Moves Taken for Sort : " + itrs + " moves.");
System.out.println("Time Taken for Sort : " + timeTaken
+ " milliseconds.");
for (int a = 0; a < BubArray.length; a++) {
System.out.print(BubArray[a] + " ");
}
}
private static int bubbleSort(int[] BubArray) {
int z = BubArray.length;
int temp = 0;
int itrs = 0;
for (int a = 0; a < z; a++) {
for (int x = 1; x < (z - a); x++) {
if (BubArray[x - 1] > BubArray[x]) {
temp = BubArray[x - 1];
BubArray[x - 1] = BubArray[x];
BubArray[x] = temp;
}
itrs++;
}
}
return itrs;
}
public static double bubbleSortTimeTaken(int[] BubArray) {
long startTime = System.nanoTime();
bubbleSort(BubArray);
long timeTaken = System.nanoTime() - startTime;
return timeTaken;
}
}
and here are the results output (note it is limited to just one run):
Unsorted List :
[13981, 6793, 2662, 733, 2850, 9581, 7744 .... ]
Sorted List with BubbleSort
Moves Taken to Sort : 1447551 Moves.
Time Taken to Sort : 1.2483121E7 Milliseconds.
[10, 11, 17, 24, 35, 53, 57, 60, 78, 89, 92 ... ]
Edited code...
public class BubbleSort {
static double bestTime = 10000000, worstTime = 0; //global variables
public static void main(String[] args) {
int BubArray[] = new int[]{3,5,3,2,5,7,2,5,8};
System.out.println("Array Before Bubble Sort");
for(int a = 0; a < BubArray.length; a++){
System.out.print(BubArray[a] + " ");
}
System.out.println("\n Entering Loop...");
for(int i=0; i<1000;i++)
{
bubbleSortTimeTaken(BubArray, i);
}
int itrs = bubbleSort(BubArray);
System.out.println("");
System.out.println("Array After Bubble Sort");
System.out.println("Moves Taken for Sort : " + itrs + " moves.");
System.out.println("BestTime: " + bestTime + " WorstTime: " + worstTime);
System.out.print("Sorted Array: \n");
for(int a = 0; a < BubArray.length; a++){
System.out.print(BubArray[a] + " ");
}
}
private static int bubbleSort(int[] BubArray) {
int z = BubArray.length;
int temp = 0;
int itrs = 0;
for(int a = 0; a < z; a++){
for(int x=1; x < (z-a); x++){
if(BubArray[x-1] > BubArray[x]){
temp = BubArray[x-1];
BubArray[x-1] = BubArray[x];
BubArray[x] = temp;
}
itrs++;
}
}
return itrs;
}
public static void bubbleSortTimeTaken(int[] BubArray, int n)
{
long startTime = System.nanoTime();
bubbleSort(BubArray);
double timeTaken = (System.nanoTime() - startTime)/1000000d;
if(timeTaken > 0)
{
if(timeTaken > worstTime)
{
worstTime = timeTaken;
}
else if(timeTaken < bestTime)
{
bestTime = timeTaken;
}
}
System.out.println("Loop number: "+n + " Time Taken: " + timeTaken);
}
}
Move the method below
private static int bubbleSort(int[] BubArray)
in to some other class extending Thread. May be you can create new threads each time execution finishes. A static instance variable in root class can be used to hold the times.
Related
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
I have the following Class with some sorting algorithms like MaxSort, BubbleSort, etc.:
class ArrayUtility {
public static int returnPosMax(int[] A, int i, int j) {
int max = i;
int position = 0;
for(int c = 0; c <= j; c++){
if(c >= i){
if(A[c] > max){
max = A[c];
position = c;
}
}
}
return position;
}
public static int returnMax(int[] A, int i, int j) {
return A[returnPosMax(A, i, j)];
}
public static void swap(int[] A, int i, int j) {
int b = A[i];
A[i] = A[j];
A[j] = b;
}
public static void MaxSort(int[] A) {
int posMax;
for(int i = A.length - 1; i >= 0; i--){
posMax = returnPosMax(A, 0, i);
swap(A, posMax, i);
}
}
public static void BubbleSort(int[] A) {
boolean flag = true;
while (flag != false){
flag = false;
for(int i = 1; i <= A.length - 1; i++){
if(A[i-1]>A[i]){
swap(A, i-1, i);
flag = true;
}
}
if(flag = false) {
break;
}
for(int i = A.length - 1; i >= 1; i--){
if(A[i-1]>A[i]){
swap(A, i - 1, i);
flag = true;
}
}
}
}
public static void BubbleSortX(int[] A) {
boolean flag = true;
while (flag != false){
flag = false;
for(int i = 1; i <= A.length - 1; i++){
if(A[i-1]>A[i]){
swap(A, i-1, i);
flag = true;
}
}
}
}
}
Now i have to create a Test Class to evaluate the different sorting algorithms for different lengths of randomly created Arrays:
import java.util.Random;
import java.util.Arrays;
public class TestSorting{
public static void main(String[] args){
int[] lengthArray = {100, 1000, 10000, 100000};
for(int i = 0; i <= lengthArray.length - 1; i++){
int[] arr = new int[i];
for(int j = 0; j < i; j++){
Random rd = new Random();
int randInt = rd.nextInt();
arr[j] = randInt;
}
/* long startTime = System.nanoTime();
ArrayUtility.MaxSort(arr);
long cpuTime = System.nanoTime() - startTime;
System.out.println("Time: " + cpuTime + " - Array with Length: " + lengthArray[i] + " Using MaxSort"); */
/* long startTime = System.nanoTime();
ArrayUtility.BubbleSortX(arr);
long cpuTime = System.nanoTime() - startTime;
System.out.println("Time: " + cpuTime + " - Array with Length: " + lengthArray[i] + " Using BubbleSortX"); */
long startTime = System.nanoTime();
ArrayUtility.BubbleSort(arr);
long cpuTime = System.nanoTime() - startTime;
System.out.println("Time: " + cpuTime + " - Array with Length: " + lengthArray[i] + " Using BubbleSort");
/*long startTime = System.nanoTime();
Arrays.sort(arr)
long cpuTime = System.nanoTime() - startTime;
System.out.println("Time: " + cpuTime + " - Array with Length: " + lengthArray[i] + " Using BubbleSort"); */
}
}
}
Now when i run a certain sorting algorithm (i set the others as comment for the meantime), i get weird results, for example
Time: 1049500 - Array with Length: 100 Using BubbleSort
Time: 2200 - Array with Length: 1000 Using BubbleSort
Time: 13300 - Array with Length: 10000 Using BubbleSort
Time: 3900 - Array with Length: 100000 Using BubbleSort
And any time i run the test i get different results, such that Arrays with 10 times the length take less time to sort, also i dont understand why the array with 100 integers takes so long.
TL;DR: your benchmark is wrong.
Explanation
To make a good benchmark, you need to do a lot of research. A good starting point is this article and this talk by Alexey Shipilev, the author of micro-benchmark toolkit JMH.
Main rules for benchmarking:
warm up! Do a bunch (like, thousands) of warmup rounds before you actually measure stuff - this will allow JIT compiler to do its job, all optimizations to apply, etc.
Monitor your GC closely - GC event can skid the results drastically
To avoid that - repeat the benchmark many (hundreds thousands) times and get the average.
All this can be done in JMH.
I took a snippet out of your code to show you where your code is buggy.
public static void main(String[] args){
int[] lengthArray = {100, 1000, 10000, 100000};
for(int i = 0; i <= lengthArray.length - 1; i++) { // this loop goes from 0 - 3
int[] arr = new int[i]; // thats why this array will be of size 0 - 3
// correct line would be:
// int[] arr = new int[lengthArray[i]];
for(int j = 0; j < i; j++) {
// correct line would be:
// for (int j = 0; j < arr.length; j++) {
...
Additionally, the hint for benchmarking from Dmitry is also important to note.
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.
I've written a bubble sort program that sorts 10000 unique values into order.
I've run the program and it gives me an output of time (using nanoTime) for the time it takes the program to complete, but I wish to add another output to the program's code; How many moves the program takes to sort from start to finish.
Here is the code:
public class BubbleSort {
public static void main(String[] args) {
int BubArray[] = new int[]{#here are 10000 integers#};
System.out.println("Array Before Bubble Sort");
for(int a = 0; a < BubArray.length; a++){
System.out.print(BubArray[a] + " ");
}
double timeTaken = bubbleSortTimeTaken(BubArray);
bubbleSort(BubArray);
System.out.println("");
System.out.println("Array After Bubble Sort");
System.out.println(" Time taken for Sort : " + timeTaken + " milliseconds.");
for(int a = 0; a < BubArray.length; a++){
System.out.print(BubArray[a] + " ");
}
}
private static void bubbleSort(int[] BubArray) {
int z = BubArray.length;
int temp = 0;
for(int a = 0; a < z; a++){
for(int x=1; x < (z-a); x++){
if(BubArray[x-1] > BubArray[x]){
temp = BubArray[x-1];
BubArray[x-1] = BubArray[x];
BubArray[x] = temp;
}
}
}
}
public static double bubbleSortTimeTaken(int[] BubArray) {
long startTime = System.nanoTime();
bubbleSort(BubArray);
long timeTaken = System.nanoTime() - startTime;
return timeTaken;
}
}
The code executes and outputs how I want it to:
Array Before Bubble Sort
13981 6793 2662 10986 733 10107 2850 ...
Array After Bubble Sort
10 11 17 24 35 53 57 60 61 78 83 89 128 131 138 141 ....
Time taken for Sort : 1.6788472E7 milliseconds.
But I wish to add another output to the code where it tells me in how many moves (basically a move counter) it takes to complete, i.e:
Time taken for Sort : 1.6788472E7 milliseconds.
Total number of moves: 3000
Does this make sense?
Any help would be appreciated, thanks.
I would change bubbleSort to return an int and assign your time complexity to it.
private static int bubbleSort(int[] BubArray) {
int z = BubArray.length;
int temp = 0;
int itrs = 0;
for(int a = 0; a < z; a++){
for(int x=1; x < (z-a); x++){
if(BubArray[x-1] > BubArray[x]){
temp = BubArray[x-1];
BubArray[x-1] = BubArray[x];
BubArray[x] = temp;
}
itrs++;
}
}
return itrs;
}
Then in main:
int itrs = bubbleSort(BubArray);
System.out.println("");
System.out.println("Array After Bubble Sort");
System.out.println(" Time taken for Sort : " + timeTaken + " milliseconds.");
System.out.println("Time complexity: " + itrs);
Try this:
// returns the number of switches
private int bubbleSort(int[] BubArray) {
int z = BubArray.length;
int temp = 0;
int timesSwitched = 0;
for(int a = 0; a < z; a++){
for(int x=1; x < (z-a); x++){
if(BubArray[x-1] > BubArray[x]){
temp = BubArray[x-1];
BubArray[x-1] = BubArray[x];
BubArray[x] = temp;
timesSwitched++
}
}
}
return timesSwitched;
}