How to determine your programs runtime? - java

I have to write a divide-and-conquer program to solve the following problem. Let A[1..n] and B[1..n] be two arrays of distinct integers, each sorted in an increasing order.Find the nth smallest of the 2n combined elements. I can not merge the two arrays. My program must be in O(log n) time.
I have written my program but have no clue how to determine if it meets the requirement of the run time.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import java.util.Scanner;
public class main {
public static void main(String[] args) {
// this section of code will require user input to have the value of n to be set
Scanner sc = new Scanner(System.in);
System.out.print(("What number would you like to set n equal to : "));
int value = sc.nextInt();
// this section of code set the two array only to hold the value of n
Random rand = new Random();
ArrayList<Integer> setA = new ArrayList<Integer>();
for (int i = 0; i < value; i++) {
int picks = rand.nextInt(1000);
setA.add(picks);
}
Collections.sort(setA);
System.out.println("A1: "+ setA);
ArrayList<Integer> setX = new ArrayList<Integer>();
for (int k = 0; k < value; k++) {
int picks = rand.nextInt(1000);
setX.add(picks);
}
Collections.sort(setX);
System.out.println("A2: "+ setX);
ArrayList<Integer> afinal = new ArrayList<Integer>();
int r = 0;
int f = 0;
int q = 0;
while(afinal.size()!= value) {
if(setA.get(r) < setX.get(f)) {
q = setA.get(r);
afinal.add(q);
r++;
}else {
q = setX.get(f);
afinal.add(q);
f++;
}
}
System.out.println("");
System.out.println(afinal);
int w = value - 1;
int ans = afinal.get(w);
System.out.println("");
System.out.println("The nth smallest integer is "+ ans);
}
}

You can calculate runtime with System.currentTimeMillis().
What we want to do is get the current time before the program runs, then get the time after the program runs. We then handle the two times accordingly.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import java.util.Scanner;
public class main {
public static void main(String[] args) {
long before = System.currentTimeMillis();
// this section of code will require user input to have the value of n to be set
Scanner sc = new Scanner(System.in);
System.out.print(("What number would you like to set n equal to : "));
int value = sc.nextInt();
// this section of code set the two array only to hold the value of n
Random rand = new Random();
ArrayList<Integer> setA = new ArrayList<Integer>();
for (int i = 0; i < value; i++) {
int picks = rand.nextInt(1000);
setA.add(picks);
}
Collections.sort(setA);
System.out.println("A1: "+ setA);
ArrayList<Integer> setX = new ArrayList<Integer>();
for (int k = 0; k < value; k++) {
int picks = rand.nextInt(1000);
setX.add(picks);
}
Collections.sort(setX);
System.out.println("A2: "+ setX);
ArrayList<Integer> afinal = new ArrayList<Integer>();
int r = 0;
int f = 0;
int q = 0;
while(afinal.size()!= value) {
if(setA.get(r) < setX.get(f)) {
q = setA.get(r);
afinal.add(q);
r++;
}else {
q = setX.get(f);
afinal.add(q);
f++;
}
}
System.out.println("");
System.out.println(afinal);
int w = value - 1;
int ans = afinal.get(w);
System.out.println("");
System.out.println("The nth smallest integer is "+ ans);
long after = System.currentTimeMillis();
}
}
In the example above, we've got the two times. Now what do we do?
We can subtract them to get the difference in times (by milliseconds).
Like so:
long ellapsedMilliseconds = after-before;
If you want to get the elapsed time in seconds, divided ellapsedMilliseconds by 100.
So the final code should be;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import java.util.Scanner;
public class main {
public static void main(String[] args) {
long before = System.currentTimeMillis();
// this section of code will require user input to have the value of n to be set
Scanner sc = new Scanner(System.in);
System.out.print(("What number would you like to set n equal to : "));
int value = sc.nextInt();
// this section of code set the two array only to hold the value of n
Random rand = new Random();
ArrayList<Integer> setA = new ArrayList<Integer>();
for (int i = 0; i < value; i++) {
int picks = rand.nextInt(1000);
setA.add(picks);
}
Collections.sort(setA);
System.out.println("A1: "+ setA);
ArrayList<Integer> setX = new ArrayList<Integer>();
for (int k = 0; k < value; k++) {
int picks = rand.nextInt(1000);
setX.add(picks);
}
Collections.sort(setX);
System.out.println("A2: "+ setX);
ArrayList<Integer> afinal = new ArrayList<Integer>();
int r = 0;
int f = 0;
int q = 0;
while(afinal.size()!= value) {
if(setA.get(r) < setX.get(f)) {
q = setA.get(r);
afinal.add(q);
r++;
}else {
q = setX.get(f);
afinal.add(q);
f++;
}
}
System.out.println("");
System.out.println(afinal);
int w = value - 1;
int ans = afinal.get(w);
System.out.println("");
System.out.println("The nth smallest integer is "+ ans);
long after = System.currentTimeMillis();
long ellapsedMilliseconds = after-before;
System.out.println("Execution time: "+elapsedMilliseconds);
}
}

Related

Compare 2 team strength and find the wining probability

TeamA = {3,6,7,5,3,5,6,2,9,1}
TeamB = {2,7,0,9,3,6,0,6,2,6}
print the maximum number of fights TeamA can win if they go to fight in an optimal manner. Consider each number in array is a member and that member fight against another member of other team. For e.g TeamA[i] will fight with TeamB[i] and TeamA[i] wins if it is greater than TeamB. With the given array order of TeamA will win only 4 one to one fight. If we re-arrange TeamA array, there is possibility to win 7 fights.i.e TeamA==> {3,9,1,5,5,7,2,6,3,6}
Below is the code which determines the output correctly but there is complexity in time due to sorting, Please help me to optimize the below code
import java.io.*;
import java.util.*;
public class FightCode{
// static long[] result ={};
public static void main(String args[] ) throws Exception {
Scanner scanner = new Scanner(System.in);
try {
int testCount = scanner.nextInt();
for (int test=0;test<testCount;test++) {
int totalMem = scanner.nextInt();
Long[] teamA = new Long[totalMem];
Long[] teamB = new Long[totalMem];
if (totalMem <1)
return;
for (int r = 0; r < totalMem; r++) {
teamA[r] = (Long)scanner.nextLong();
}
for (int i = 0; i < totalMem; i++) {
teamB[i] = (Long)scanner.nextLong();
}
int count = 0;
// int[]swapar = new int[totalMem];
Arrays.sort(teamB, Collections.reverseOrder());
Arrays.sort(teamA, Collections.reverseOrder());
boolean result = Arrays.equals(teamA, teamB);
if (result)
return;
// System.out.println(Arrays.toString(teamB));
// System.out.println(Arrays.toString(teamA));
for (int a = 0; a < totalMem; a++) {
for (int k=0;k<totalMem;k++) {
if(teamA[k] > teamB[a]){
// swapar[a] = teamA[k];
teamA[k] = 0L;
count++;
break;
}
}
}
// System.out.println(Arrays.toString(swapar));
System.out.println(count);
}
} catch(Exception e) {
System.err.println(e.getStackTrace().toString());
} finally {
scanner.close();
}
}
}
This question was asked on techgig Code Gladiator 2020.
Instead of looping over entire team B in range 0 to k-1, you can loop between x and k-1 , where x is last index in team B where last match was found.
for (int a = 0; a < totalMem; a++) {
for (int k=minIndex;k<a-1;k++) {
if(teamA[a] > teamB[k]){
// swapar[a] = teamA[k];
minIndex=k+1;
count++;
break;
}
}
}

BFS using Adjecency Matrix

Question to find Bfs path ,, i am able to code bfs path if the graph have vertices marked as 0,1,2,3,4,,like this
But can't able to apply adjacency matrix how to solve bfs for graph like 5,10,15,20
attached images what i have coded
solution
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Bfs {
public static void bfsTraversal(int[][] adjMatrix) {
Queue<Integer> pendingVertices = new LinkedList<>();
boolean[] visited = new boolean[adjMatrix.length];
visited[0] = true;
pendingVertices.add(0);
while (!pendingVertices.isEmpty()) {
int currentVertex = pendingVertices.poll();
System.out.print(currentVertex + " ");
for (int i = 0; i < adjMatrix.length; i++) {
if (adjMatrix[currentVertex][i] == 1 && !visited[i]) {
pendingVertices.add(i);
visited[i] = true;
}
}
}
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int v = s.nextInt();
int e = s.nextInt();
int[][] adjMatrix = new int[v][v];
for (int i = 0; i < e; i++) {
int v1 = s.nextInt();
int v2 = s.nextInt();
adjMatrix[v1][v2] = 1;
adjMatrix[v2][v1] = 1;
}
bfsTraversal(adjMatrix);
}
}
Click here for Question for bfs like vertices 0,1,2,3,4...
Click here for ,How i want to solve this for bfs like vertices 5,10,15,20...
And i want to do the same for graph like this ,,can't get logic
Solved by mapping the input with 0,1,2,3.... and maintained a reverseMap
Click here to view the Solution
If you know the range of the numbers, you can let the numbers 5, 10, 15 and 20 be the IDs of the nodes and store the indices of the nodes in a seperate array. Suppose the name of the array is IndexLookupArray, if you want to lookup the index of a node with ID x you can find it in IndexLookupArray[x]. And the rest of the code should be the same. If the range of the numbers is unknown or if it's too big to fit in an array, you can store the indices in a hash map for example and do the same thing.
You can write something like this:
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Bfs {
public static void bfsTraversal(int[][] adjMatrix) {
Queue<Integer> pendingVertices = new LinkedList<>();
boolean[] visited = new boolean[adjMatrix.length];
visited[0] = true;
pendingVertices.add(0);
while (!pendingVertices.isEmpty()) {
int currentVertex = pendingVertices.poll();
System.out.print(currentVertex + " ");
for (int i = 0; i < adjMatrix.length; i++) {
if (adjMatrix[currentVertex][i] == 1 && !visited[i]) {
pendingVertices.add(i);
visited[i] = true;
}
}
}
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int idx = 0;
int range = s.nextInt();
int v = s.nextInt();
int e = s.nextInt();
int[] IndexLookupArray = new int[range + 1]; // range + 1 since IndexLookupArray[range] should be accessible.
int[][] adjMatrix = new int[v][v];
Arrays.fill(IndexLookupArray, 0, range + 1, -1);
for (int i = 0; i < e; i++) {
int v1 = s.nextInt();
if (IndexLookupArray[v1] == -1)
{
IndexLookupArray[v1] = idx;
idx++;
}
v1 = IndexLookupArray[v1];
int v2 = s.nextInt();
if (IndexLookupArray[v2] == -1)
{
IndexLookupArray[v2] = idx;
idx++;
}
v2 = IndexLookupArray[v2];
adjMatrix[v1][v2] = 1;
adjMatrix[v2][v1] = 1;
}
bfsTraversal(adjMatrix);
}
}

Why is using an object array a better idea in this code?

Our assignment was to solve the Hackerrank question on arraylist without using 2D arrays or lists. Basically, you would need to input multiple arrays of different sizes and display an element based on the input of (array number, position). My implementation seemed to work just fine for my test cases but failed 4/6 of Hackerrank's test cases. Our lecturer's code (of course) worked perfectly. But what I fail to understand, is advantage of his approach:
My Code ::
import java.io.PrintStream;
import java.util.Scanner;
class arraylist {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int NoOfLines = sc.nextInt();
int[] input = new int[20000];//To store all input arrays one after the other in one 1D array.
int[] index = new int[NoOfLines];//Starting positions of each array input.
int[] NoOfArrayElements = new int[NoOfLines];//Sizes of each corresponding input array.
int position = 0;
int count = 0;
int arrayelementpos = 0;
//Store the input and note the size of each array and the index position.
for (int i = 0; i < NoOfLines; i++) {
int arrarLength = sc.nextInt();
NoOfArrayElements[arrayelementpos++] = arrarLength;
index[position++] = count;
for (int j = 0; j < arrarLength; j++)
input[count++] = sc.nextInt();
}
//Code to input queries (array no, element position)
int NoOfQueries = sc.nextInt();
int[] result = new int[NoOfQueries];
int pos = 0;
for (int i = 0; i < NoOfQueries; i++) {
int arrayNo = sc.nextInt();
int element = sc.nextInt();
if ((arrayNo > NoOfLines) || element > NoOfArrayElements[arrayNo - 1]) {
System.out.println("ERROR!");
continue;
}
pos = index[arrayNo - 1] + element - 1;
System.out.println("THE ELEMENT IS ::" + input[pos]);
}
}
}
My lecturer's code ::
import java.io.*;
import java.util.*;
public class arraylistsolved {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Object [] store=new Object[n];
for(int i=0; i<n;i++){
int d=sc.nextInt();
int [] ar=new int[d];
for(int j=0;j<d;j++) {
ar[j]=sc.nextInt();
}
store[i]=ar;
}
int q=sc.nextInt();
for(int i=0;i<q;i++){
int array=sc.nextInt()-1;
int element=sc.nextInt()-1;
Object obj=store[array];
int [] retrieve = (int []) obj;
if(array>n||element>retrieve.length-1)
System.out.println("ERROR!");
else
System.out.println(retrieve[element]);
}
}
}
As mentioned, both the codes are working for small test cases, but mine breaks down for very large ones for some reason. You can try copy-pasting the code here: https://www.hackerrank.com/challenges/java-arraylist/problem

Java fill an array with random with random numbers

I have a homework assignment where a user must input the size of an array and then the array must be filled with random values. I am having issues filling the array with something that isn't garbage values. I am sure there are other issues with my code as well but this is the biggest issue I'm currently trying to solve. Any help would be appreciated.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import java.util.*;
public class rotateArray1
{
public static int randomFill()
{
Random rand = new Random();
int randomInt = rand.nextInt();
return randomInt;
}
void leftRotate(int arr[], int d, int n)
{
int i;
for(i=0; i < d; i++)
leftRotateByOne(arr, n);
}
void leftRotateByOne(int arr[], int n)
{
int i,temp;
temp = arr[0];
for(i=0; i < n -1; i++)
arr[i] = arr[i+1];
arr[i] = temp;
}
void printArray(int arr[],int size)
{
int i;
for (i = 0; i<size;i++)
System.out.print(arr[i]+ "");
}
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter size of array");
int x= input.nextInt();
int[] arr = new int[x];
for(int i = 0; i<x; i++){
arr[i] = randomFill();
}
rotateArray rotate = new rotateArray();
rotate.leftRotate(arr, 2, x);
rotate.printArray(arr, x);
System.exit(0);
}
}
Just pass a reference to the array to randomFill and do it in one shot. That helps the code in main() read easier and uses one instance of a Random which is probably more what you want as was pointed out.
import java.util.Random;
public class JavaTest {
public static void main(String... args) {
int[] array = new int[10];
randomFill(array);
for(int i = 0; i < array.length ; i++){
System.out.println("array["+i+"] = "+array[i]);
}
}
static void randomFill(int[] array)
{
Random rand = new Random();
for(int i = 0; i < array.length ; i++){
array[i] = rand.nextInt();
}
}
}
Output:
array[0] = 431970257
array[1] = 9846759
array[2] = 1919609165
array[3] = -544686432
array[4] = 655372436
array[5] = -331654257
array[6] = -1187729012
array[7] = 1378209257
array[8] = -1225327561
array[9] = 1887304192

Using 10 Threads to Process an Array

I'm working to improve my java skills but a little unsure on how to handle this multi-threaded application. Basically, the program reads a text file and finds the largest number. I added a for loop within my search algorithm to create 10 threads but I'm not sure if it's actually creating 10 threads. The idea is to improve the execution time, or at least that's what I assume should happen. Is there anyway to check if I did it correctly and if the execution time is indeed improved?
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ProcessDataFile {
public static void main(String[] args) throws IOException {
int max = Integer.MIN_VALUE;
int i = 0;
int[] numbers = new int[100000];
String datafile = "dataset529.txt"; //string which contains datafile
String line; //current line of text file
try (BufferedReader br = new BufferedReader(new FileReader(datafile))) { //reads in the datafile
while ((line = br.readLine()) != null) { //reads through each line
numbers[i++] = Integer.parseInt(line); //pulls out the number of each line and puts it in numbers[]
}
}
for (i = 0; i < 10000; i++){ //loop to go through each number in the file and compare it to find the largest int.
for(int j = 0; j < 10; j++) { //creates 10 threads
new Thread();
}
if (max < numbers[i]) //As max gets bigger it checks the array and keeps increasing it as it finds a larger int.
max = numbers[i]; //Sets max equal to the final highest value found.
}
System.out.println("The largest number in DataSet529 is: " + max);
}
}
This is a VERY basic example which demonstrates the basic concepts of creating and running threads which process a given range of values from a specific array. The example makes a few assumptions (only a even number of elements for example). The example is also slightly long winded and is done so deliberately, in an attempt to demonstrate the basic steps which would be needed
Start by taking a look at the Concurrency Trail for more details
import java.util.Random;
public class ThreadExample {
public static void main(String[] args) {
int[] numbers = new int[100000];
Random rnd = new Random();
for (int index = 0; index < numbers.length; index++) {
numbers[index] = rnd.nextInt();
}
Thread[] threads = new Thread[10];
Worker[] workers = new Worker[10];
int range = numbers.length / 10;
for (int index = 0; index < 10; index++) {
int startAt = index * range;
int endAt = startAt + range;
workers[index] = new Worker(startAt, endAt, numbers);
}
for (int index = 0; index < 10; index++) {
threads[index] = new Thread(workers[index]);
threads[index].start();
}
boolean isProcessing = false;
do {
isProcessing = false;
for (Thread t : threads) {
if (t.isAlive()) {
isProcessing = true;
break;
}
}
} while (isProcessing);
for (Worker worker : workers) {
System.out.println("Max = " + worker.getMax());
}
}
public static class Worker implements Runnable {
private int startAt;
private int endAt;
private int numbers[];
private int max = Integer.MIN_VALUE;
public Worker(int startAt, int endAt, int[] numbers) {
this.startAt = startAt;
this.endAt = endAt;
this.numbers = numbers;
}
#Override
public void run() {
for (int index = startAt; index < endAt; index++) {
max = Math.max(numbers[index], max);
}
}
public int getMax() {
return max;
}
}
}
A slightly simpler solution would involve the ExecutorService API, which would allow you to offer a series of Callables to the service which would then return a List of Future's. The benefit here is, the service won't return till all the Callables have completed (or have failed), so you don't need constantly check the states of the threads
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadExample {
public static void main(String[] args) {
int[] numbers = new int[100000];
Random rnd = new Random();
for (int index = 0; index < numbers.length; index++) {
numbers[index] = rnd.nextInt();
}
ExecutorService executor = Executors.newFixedThreadPool(10);
Worker[] workers = new Worker[10];
int range = numbers.length / 10;
for (int index = 0; index < 10; index++) {
int startAt = index * range;
int endAt = startAt + range;
workers[index] = new Worker(startAt, endAt, numbers);
}
try {
List<Future<Integer>> results = executor.invokeAll(Arrays.asList(workers));
for (Future<Integer> future : results) {
System.out.println(future.get());
}
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
public static class Worker implements Callable<Integer> {
private int startAt;
private int endAt;
private int numbers[];
public Worker(int startAt, int endAt, int[] numbers) {
this.startAt = startAt;
this.endAt = endAt;
this.numbers = numbers;
}
#Override
public Integer call() throws Exception {
int max = Integer.MIN_VALUE;
for (int index = startAt; index < endAt; index++) {
max = Math.max(numbers[index], max);
}
return max;
}
}
}
I know this is a bit late answer but you can also use lambda expressions while using ExecutorService instead of creating new class that implements Runnable.
Here is a complete example below, you can play around THREAD_SIZE and RANDOM_ARRAY_SIZE variables.
import org.apache.log4j.Logger;
import java.security.SecureRandom;
import java.util.*;
import java.util.concurrent.*;
public class ConcurrentMaximumTest {
static final int THREAD_SIZE = 10;
static final int RANDOM_ARRAY_SIZE = 8999;
static final SecureRandom RAND = new SecureRandom();
private static Logger logger = Logger.getLogger(ConcurrentMaximumTest.class);
public static void main(String[] args) throws InterruptedException, ExecutionException {
int[] array = generateRandomIntArray(RANDOM_ARRAY_SIZE);
Map<Integer, Integer> positionMap = calculatePositions(array.length, THREAD_SIZE);
ExecutorService threads = Executors.newFixedThreadPool(THREAD_SIZE);
List<Callable<Integer>> toRun = new ArrayList<>(THREAD_SIZE);
for (Map.Entry<Integer, Integer> entry : positionMap.entrySet())
toRun.add(() -> findMax(array, entry.getKey(), entry.getValue()));
int result = Integer.MIN_VALUE;
List<Future<Integer>> futures = threads.invokeAll(toRun);
for (Future<Integer> future : futures) {
Integer localMax = future.get();
if(localMax > result)
result = localMax;
}
threads.shutdownNow();
logger.info("Max value calculated with " + THREAD_SIZE + " threads:" + result);
Arrays.sort(array);
int resultCrosscheck = array[array.length - 1];
logger.info("Max value calculated with sorting: " + resultCrosscheck);
assert result != resultCrosscheck : "Crosscheck failed";
}
/* Calculates start and end positions of each chunk(for simplicity). It can also be calculated on the fly.*/
private static Map<Integer, Integer> calculatePositions(int size, int numThreads){
int lengthOfChunk = size / numThreads;
int remainder = size % numThreads;
int start = 0;
Map<Integer,Integer> result = new LinkedHashMap<>();
for(int i = 0; i < numThreads -1; i++){
result.put(start, lengthOfChunk);
start += lengthOfChunk;
}
result.put(start, lengthOfChunk+remainder);
return result;
}
/*Find maximum value of given part of an array, from start position and chunk size.*/
private static int findMax(int[] wholeArray, int position, int size){
int end = (position + size);
int max = Integer.MIN_VALUE;
logger.info("Starting read for interval [" + position + "," + end + ")");
for(int i = position; i < (position + size); i++)
if(wholeArray[i] > max)
max = wholeArray[i];
logger.info("Finishing finding maximum for interval [" + position + "," + end + ")" + ". Calculated local maximum is " + max);
return max;
}
/* Helper function for generating random int array */
private static int[] generateRandomIntArray(int size){
int[] result = new int[size];
for (int i = 0; i < size; i++)
result[i] = RAND.nextInt(Integer.MAX_VALUE);
return result;
}
}

Categories