RandomizedQuickSort method for arrays - java

IS there RandomizedQuickSort method in java API? OR we should write its code ourselves?
thanks

Unless you know that Arrays.sort() is not going to work for you, I suggest you use that. Otherwise I suggest you test any alternative is as good as it suggests.
I added the following to the source suggested by #org.life.java as well as a shuffle()/sort() methods which should be both randomised and quicksorted.
long runTimeNS = 2 * 1000 * 1000 * 1000L;
for (int i = 0; i < 3; i++) {
long start = System.nanoTime();
long r;
for (r = 1; r < runTimeNS; r++) {
Arrays.sort(list7.clone());
if (System.nanoTime() - start > runTimeNS) break;
}
long time = System.nanoTime() - start;
System.out.println("Average Arrays.sort() time " + time / r / 1000 + " us.");
long start1 = System.nanoTime();
for (r = 1; r < runTimeNS; r++) {
List<Integer> list = new ArrayList<Integer>();
for (int j : list7) list.add(j);
Collections.shuffle(list);
Collections.sort(list);
int[] ints = new int[list.size()];
for (int j = 0; j < list.size(); j++) ints[j] = list.get(j);
if (System.nanoTime() - start1 > runTimeNS) break;
}
long time1 = System.nanoTime() - start1;
System.out.println("Average shuffle/sort time " + time1 / r / 1000 + " us.");
long start2 = System.nanoTime();
for (r = 1; r < runTimeNS; r++) {
qrsort(list7.clone());
if (System.nanoTime() - start2 > runTimeNS) break;
}
long time2 = System.nanoTime() - start2;
System.out.println("Average qrsort() time " + time2 / r / 1000 + " us.");
}
and it prints
Average Arrays.sort() time 477 us.
Average shuffle/sort time 5964 us.
Average qrsort() time 36155 us.
Average Arrays.sort() time 474 us.
Average shuffle/sort time 5894 us.
Average qrsort() time 35078 us.
Average Arrays.sort() time 480 us.
Average shuffle/sort time 6211 us.
Average qrsort() time 34790 us.

Related

How to make java code perform better in for loop?

When executed once, code 1 is faster than code 2. The difference is quite significant.
But, when these codes are executed inside for loop (50 million times, see code 1 inside for loop and code 2 inside for loop) code 1 has the worst performance.
Is it possible to make code 1 perform better inside for loop?
Another question: is there another way to do these calculations inside for loop with a better performance?
int [] arr1 = new int[50000000];
for (int i = 0; i < 50000000; i++) {
arr1[i] = i + 1000;
}
//code 1:
long startTime1 = System.nanoTime();
int som1 = 426;
double a1 = (double) ((((double) Math.round((double) Math.pow((double) arr1[arr1.length - 1] / (double) som1, 2)) - 1) / 50 % 1) * 50) + 1;
int a2 = (int) Math.round(a1);
long estimatedTime1 = System.nanoTime() - startTime1;
System.out.println("Code 1: " + estimatedTime1);
//code 2:
long startTime2 = System.nanoTime();
int som2 = 426;
double a3 = (double) arr1[arr1.length - 1] / (double) som2;
double a4 = (double) (Math.round(a3 * a3) - 1);
double a5 = (double) a4 / 50;
double a6 = (double) Math.floor(a5);
double a7 = (double) ((a5 - a6) * 50) + 1;
int a8 = (int) Math.round(a7);
long estimatedTime2 = System.nanoTime() - startTime2;
System.out.println("Code 2: " + estimatedTime2);
//code 1 inside for loop:
long startTime3 = System.nanoTime();
int som3 = 426;
for (int j1 = 0; j1 < arr1.length; j1++) {
double a9 = (double) ((((double) Math.round((double) Math.pow((double) arr1[j1] / (double) som1, 2)) - 1) / 50 % 1) * 50) + 1;
int a10 = (int) Math.round(a9);
}
long estimatedTime3 = System.nanoTime() - startTime3;
System.out.println("Code 1 inside for loop: " + estimatedTime3);
//code 2 inside for loop:
long startTime4 = System.nanoTime();
int som4 = 426;
for (int j2 = 0; j2 < arr1.length; j2++) {
double a11 = (double) arr1[j2] / (double) som4;
double a12 = (double) (Math.round(a11 * a11) - 1);
double a13 = (double) a12 / 50;
double a14 = (double) Math.floor(a13);
double a15 = (double) ((a13 - a14) * 50) + 1;
int a16 = (int) Math.round(a15);
}
long estimatedTime4 = System.nanoTime() - startTime4;
System.out.println("Code 2 inside for loop: " + estimatedTime4);
Edit : As explained by #Sweeper, code 1 is slower in both cases. As I am trying to improve the performance of this code inside for loop, I would like to ask if there is a faster way to do these calculations inside for loop.

Timing methods in Java produces incorrect values?

I tried outputting the average time it takes to run a particular method using System.currentTimeMillis():
for (int i = 1; i <= 18; i++) {
int n = (int) Math.pow(2, i);
double total_time = 0;
for (int j = 1; j <= 5; j++) {
long startTime = System.currentTimeMillis();
runMethod();
long endTime = System.currentTimeMillis();
double difference = (double) (endTime - startTime);
total_time += difference / 1000;
}
System.out.println("N = " + Integer.toString(n) +": " + Double.toString(total_time / 5) + " s");
}
However, I tried timing this myself between reported times in standard output but it seems to be way off (for one iteration, I timed it to be around 30 seconds but it reported 8). Is this the wrong method to use? Or am I implementing it incorrectly?
Is it possible that the standard output is delayed, such that the actual time is not reported until well after the method has finished, so that I would myself calculate a longer time based on what is shown in the output?
As others have observed:
- don't cast to double until you need to
- use System.nanoTime() instead of System.currentTimeMillis()
This is what it could look like:
for (int i = 1; i <= 18; i++) {
final int n = 1 << i; // = 2**i
/**/ long total_time = 0;
for (int j = 1; j <= 5; j++) {
final long t0 = System.nanoTime();
runMethod();
total_time += (System.nanoTime() - t0);
}
System.out.println("N = " + n + ": " + ((double)total_time / 1_000 / 1_000 / 1_000 / 5) + " s");
System.out.println("N = " + n + ": " + ((double)total_time / 1_000 / 1_000 / 5) + " ms");
System.out.println("N = " + n + ": " + ((double)total_time / 1_000 / 5) + " μs");
System.out.println("N = " + n + ": " + ((double)total_time / 5) + " ns");
}
you should do like this
long startTime = System.currentTimeMillis();
runMethod();
long endTime = System.currentTimeMillis();

Java: Palindrome, not getting biggest number

I want to get the largest palindrome number of 3-digit numbers. This is my code:
for (int start = 100; start < 1000; start++) {
for (int start2 = 100; start2 < 1000; start2++) {
int temp = start * start2;
int biggest = 1;
String strTemp = temp + "";
if (strTemp.equals(new StringBuilder(strTemp).reverse().toString())) {
if (temp > biggest) {
biggest = temp;
System.out.println("Original: " + strTemp);
System.out.println("Reverse: " + new StringBuilder(strTemp).reverse().toString());
System.out.println("Siffra: " + start);
System.out.println("Siffra2: " + start2);
}
}
}
In the end, I get 995 x 583 and not 993 x 913, which is the largest one. Why? I have it so the int biggest always chooses the biggest number.
You need to move int biggest = 1; out of both for loops.
If you don't do that at every inner loop you restart the value of biggest.
int biggest = 1;
for (int start = 100; start < 1000; start++) {
for (int start2 = 100; start2 < 1000; start2++) {
int temp = start * start2;
String strTemp = temp + "";
if (strTemp.equals(new StringBuilder(strTemp).reverse().toString())) {
if (temp > biggest) {
biggest = temp;
System.out.println("Original: " + strTemp);
System.out.println("Reverse: " + new StringBuilder(strTemp).reverse().toString());
System.out.println("Siffra: " + start);
System.out.println("Siffra2: " + start2);
}
}
}
With java 8 you can rewrite this code as follow:
// Define what it means palindrome
IntPredicate isPalindrome = n -> new StringBuffer(String.valueOf(n)).reverse().toString().equals(String.valueOf(n));
OptionalInt max =
// Define a stream from 100 to 1000
IntStream.range(100, 1000)
// Map the original stream to a new stream
// Basically for each x of the first stream
// creates a new stream 100-1000 and map each element
// x of the first stream and y of the second stream
// to x * y
.flatMap(x -> IntStream.range(100, 1000).map(y -> x * y))
// Take only palyndrome of x * y
.filter(isPalindrome)
// take the max
.max();
A functional approach is more readable in most cases where you have to loop over n elements and is easier to filter and extract elements without
doing errors.
Move your declaration of biggest outside the loops:
int biggest = 1;
for (int start = 100; start < 1000; start++) {
for (int start2 = 100; start2 < 1000; start2++) {
int temp = start * start2;
String strTemp = temp + "";
if (strTemp.equals(new StringBuilder(strTemp).reverse().toString())) {
if (temp > biggest) {
biggest = temp;
System.out.println("Original: " + strTemp);
System.out.println("Reverse: " + new StringBuilder(strTemp).reverse().toString());
System.out.println("Siffra: " + start);
System.out.println("Siffra2: " + start2);
}
}
}
Output:
....
Original: 906609
Reverse: 906609
Siffra: 913
Siffra2: 993
int biggest = 1;
for (int start = 100; start < 1000; start++) {
for (int start2 = 100; start2 < 1000; start2++) {
int temp = start * start2;
in above you are initializing biggest=1 always. so you not getting proper result. Keep it outside of for loop.

Finding highest frequency from the recorded sound-includes FFT

I am working on a project where i have to create a Tone Listener such that i can record a tone using AudioRecord class of Android. This tone listener will listen to the tone and then will give out the frequency of the tone. I am using FFT for getting the frequency but am stuck as it does not give me the exact frequency. Is there any way that can work?
I am in search of FFT and audio record class of android.
The snippet of the code is as follows:
while (isListening) {
for (int t = 0; t <= 5; t++) {
// System.out.println("Inside for loop");
int numberOfShortsRead = audioRecord
.read(audioData,
audioSize,
(kRecorderNumberOfSamples - audioSize));
// System.out.println("Read"+numberOfShortsRead);
if (numberOfShortsRead > 0) {
System.out.println("inside read>0");
System.out.println("Number of read"
+ numberOfShortsRead);
audioSize += numberOfShortsRead;
System.out
.println("Final audio data size"
+ audioSize);
System.out.println("Number Of Samples"
+ kRecorderNumberOfSamples);
if (kRecorderNumberOfSamples == audioSize) {
for (int i = 0; i < audioSize; i++) {
x[i] = audioData[i]; // real
y[i] = 0; // imaginary
}
System.out.println("Inside FFT"
+ "x" + x + "y" + y);
int i, j, k, n1, n2, a;
double c, s, t1, t2;
// Bit-reverse
j = 0;
n2 = n / 2;
for (i = 1; i < n - 1; i++) {
n1 = n2;
while (j >= n1) {
j = j - n1;
n1 = n1 / 2;
}
j = j + n1;
if (i < j) {
t1 = x[i];
x[i] = x[j];
x[j] = t1;
t1 = y[i];
y[i] = y[j];
y[j] = t1;
}
}
// FFT
n1 = 0;
n2 = 1;
for (i = 0; i < m; i++) {
n1 = n2;
n2 = n2 + n2;
a = 0;
for (j = 0; j < n1; j++) {
c = cos[a];
s = sin[a];
a += 1 << (m - i - 1);
for (k = j; k < n; k = k
+ n2) {
t1 = c * x[k + n1] - s
* y[k + n1];
t2 = s * x[k + n1] + c
* y[k + n1];
x[k + n1] = x[k] - t1;
y[k + n1] = y[k] - t2;
x[k] = x[k] + t1;
y[k] = y[k] + t2;
}
}
}
Frequency estimation methods, such as parabolic interpolation of windowed FFT magnitude peaks (or Sinc interpolation of the complex FFT results) might provide a closer estimate of an exact frequency, as will using more data with a longer FFT, which provides more closely spaced FFT frequency result bins. You may have to buffer up more recorded samples until you have enough use that longer FFT. Zero-padding before a longer FFT is also another method of interpolation for frequency estimation, but the result will be noisier and thus less accurate than using more data.
Assuming your FFT algorithm works, to get the most prominent frequency in your audio data you have to find the frequency where the magnitude is greatest.So in other words find the FFT data point(s) that have the highest magnitude.If you want a more precise values of frequencies you will need to use a higher N to get more resolution.
Hope that helped

Overcoming heap overflow issues

I tried to solve problems from Project Euler. I know my method would work logically (it returns answers to the small scale problem almost instantly). However, it scales horribly. I already attempted changing the .ini file, but to no avail.
Here's my code:
public class Number28 {
static int SIZE = 101; //this should be an odd number, i accidentally posted 100
/**
* #param args
*/
public static void main(String[] args) {
double start = System.currentTimeMillis();
long spiral[][]= spiral(SIZE);
long sum = 0;
for(int i = 0; i < SIZE; i++)
{
sum += spiral[i][i];
sum += spiral[i][SIZE - 1 - i];
}
System.out.println(sum - 1);
double time = System.currentTimeMillis() - start;
System.out.println(time);
}
public static long[][] spiral(int size){
long spiral[][]= new long[size][size];
if(size == 1){
spiral[0][0] = 1;
return spiral;
}
else{
long subspiral[][]= new long[size - 2][size - 2];
subspiral = spiral(size - 2);
for(int r = 0; r < size - 2; r++){
for(int c = 0; c < size - 2; c++){
spiral[r + 1][c + 1] = subspiral[r][c];
}
}
long counter = subspiral[0][size - 3];
for(int r = 1; r < size ; r++){
counter++;
spiral[r][size - 1] = counter;
}
for(int c = size - 2; c >= 0; c--){
counter++;
spiral[size - 1][c] = counter;
}
for(int r = size - 2 ; r >= 0 ; r--){
counter++;
spiral[r][0] = counter;
}
for(int c = 1; c < size ; c++){
counter++;
spiral[0][c] = counter;
}
return spiral;
}
}
}
Here's the edited code, worked like a gem:
public class Number28 {
static int SIZE = 1001;
static long spiral[][]= new long[SIZE][SIZE];
/**
* #param args
*/
public static void main(String[] args) {
double start = System.currentTimeMillis();
long spiral[][]= spiral(SIZE);
long sum = 0;
for(int i = 0; i < SIZE; i++)
{
sum += spiral[i][i];
sum += spiral[i][SIZE - 1 - i];
}
System.out.println(sum - 1);
double time = System.currentTimeMillis() - start;
System.out.println(time);
}
public static long[][] spiral(int size){
if(size == 1){
spiral[SIZE / 2][SIZE / 2] = 1;
return spiral;
}
else{
long subspiral[][]= spiral(size - 2);
int edge = (SIZE - size) / 2;
long counter = subspiral[edge + 1][edge + size - 2];
for(int r = 1; r < size ; r++){
counter++;
spiral[edge + r][edge + size - 1] = counter;
}
for(int c = size - 2; c >= 0; c--){
counter++;
spiral[edge + size - 1][edge + c] = counter;
}
for(int r = size - 2 ; r >= 0 ; r--){
counter++;
spiral[edge + r][edge] = counter;
}
for(int c = 1; c < size ; c++){
counter++;
spiral[edge][edge + c] = counter;
}
return spiral;
}
}
}
As a general piece of Project Euler advice, if your solution doesn't scale, there's almost certainly a better way to solve it. If you've used the same type of solution on an earlier problem you can go through the posts from other users on the earlier question to get ideas for solving the problem in different ways.
Not familiar with the Euler problems, but the horror appears to be your continual allocation and re-allocation of what are basically throwaway intermediate spirals, as you call down recursively to the base case.
Restructure so that you allocate your full spiral up front. Then call your recursive function, passing your full spiral in as a parameter by reference, along with a "level" parameter, which will change with each recursive call. E.g., initial call is with 100x100 spiral and level 100; next (recursive) call is with same spiral, by reference, and level 98. Operations within the function will all be done on the one-and-only-allocated spiral.
In a nutshell: allocate your data structure once, even if you operate on that data structure recursively.
The first problem I saw was a NegativeArraySizeException when running your program with SIZE = 100. I guess this has something to do with how each recursive call is decreasing the size by 2.
I believe that Steven's comment is right on the money. You are allocating the size of the array, them making a recursive call. This causes (SIZE - 1) number of arrays to be allocating, eating up all of your memory. Removing that one line should prevent any memory from being allocated until necessary.
Here is a simplified solution that doesn't store a matrix:
public class P28 {
private final static int N = 1001;
public static void main(String[] args) {
int limit = (N + 1) / 2;
int sum = -3;
int first = 4;
int r = 20;
for (int i = 1; i <= limit; i++) {
sum += first;
first += r;
r += 32;
}
System.out.println(sum);
}
}
Explanation:
Starting from 1 you can see 4 sums:
1 + 3 + 13 + 31 + 57 + ...
1 + 5 + 17 + 37 + 65 + ...
1 + 7 + 21 + 43 + 73 + ...
1 + 9 + 25 + 49 + 81 + ...
1 is added 4 times, this is why the default value for sum is -3.
Let's gather those sums:
4 + 24 + 76 + 160 + 276 + ...
(this is why first is 4 and r is 20 = 24 - 4)
You can observe that r increases by 32 per step ( 24 - 4 = 32 + 76 - 24 = 32 + 32 + 160 - 76 = ... ) and the actual number (first) increases by r.

Categories