Okay firstly I'm sorry I know that I'm not intelligent enough. I'm bad at Math.
I couldn't write an algorithm to this question.
System gives us int x, int y, int boundary and wants us to find which numbers up to boundary satisfy the rule as
some_number = x^i + y^j
Boundary <= 10^6
i and j > = 0
x and y < 100
for example x = 2, y = 3 and boundary= 5,
2 = 2^0 + 3^0
3 = 2^1 + 3^0
4 = 2^0 + 3^1
5 = 2^1 + 3^1
output : 2,3,4,5
import java.util.ArrayList;
public class Main {
public static ArrayList<Integer> find_numbers(int x, int y, int boundary) {
ArrayList<Integer> res = new ArrayList<Integer>();
int num = 0;
int remain_x = 0, remain_y = 0;
int count_x = 0, count_y = 0;
if (boundary >= 2) {
res.add(2);
}
for (int i = 3; i <= boundary; ++i) {
if(i == x+y)
res.add(i);
count_x = 0;
count_y = 0;
num = i;
while (num > 0) {
remain_x = num % x;
if (remain_x == 0) {
count_x++;
} else {
while (num > 0) {
remain_y = num % y;
if (remain_y == 0) {
count_y++;
}
num = num / y;
}
}
num = num / x;
}
System.out.println("i =>" +i);
System.out.println("x=>" + count_x);
System.out.println("y =>" + count_y);
}
return res;
}
public static void main(String[] args) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x = 1 + (int) (Math.random() * 100);
int y = 1 + (int) (Math.random() * 100);
int boundary = 1 + (int) (Math.random() * 1000000);
res = find_numbers(x, y, boundary );
System.out.println(res);
}
}
Edit:
I wrote something after reading Shark's comment thank you so much. it's working.
import java.util.ArrayList;
public class Main {
public static ArrayList<Integer> find_numbers(int x, int y, int boundary) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x_k = 0;
int y_k= 0;
while(Math.pow(x,x_k)< boundary){
x_k++;
}
while(Math.pow(y,y_k)< boundary){
y_k++;
}
for(int k = 2 ; k<= boundary;++k) {
for (int i = 0; i < x_k; ++i) {
for (int j = 0; j < y_k; ++j) {
if(k == (int)Math.pow(x,i)+(int)Math.pow(y,j) && !res.contains(k)){
System.out.println("----------------------------------------");
System.out.println(k +" =>" +x + "^" +i +"+"+y+ "^" +j);
res.add(k);
}
}
}
}
return res;
}
public static void main(String[] args) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x = 1 + (int) (Math.random() * 100);
int y = 1 + (int) (Math.random() * 100);
int boundary = 1 + (int) (Math.random() * 1000000);
res = find_numbers(x, y,boundary);
System.out.println("x:" + x);
System.out.println("y:" + y);
System.out.println("boundary:" + boundary);
System.out.println("Result:" + res);
}
}
I am not sure if this is the most efficient method. Basically, I increment j until x^i + y^j > boundary then increment i.
public static ArrayList<Integer> findNumbers(int x, int y, int boundary) {
Set<Integer> result = new HashSet<>(); // make sure result is unique
int powerX = 0, powerY = 0, total = 0, tempX = 0;
while (true) {
// calculate x^i
tempX = (int) Math.pow(x, powerX);
while (true) {
// calculate x^i + y^j and compare against boundary
if ((total = tempX + (int) Math.pow(y, powerY)) <= boundary) {
// add result to set and increment y
result.add(total);
powerY++;
// break if y <= 1
if (y <= 1)
break;
} else
break;
}
// break if x <= 1 || x^i > boundary
if (tempX > boundary || x <= 1)
break;
// reset j and increment i
powerY = 0;
powerX++;
}
// return sorted result
ArrayList<Integer> arr = new ArrayList<>();
arr.addAll(result);
arr.sort(null);
return arr;
}
You might be able refactor the code for better efficiency.
public class Main {
public static ArrayList<Integer> find_numbers(int x, int y, int boundary) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x_k = 0;
int y_k= 0;
while(Math.pow(x,x_k)< boundary){
x_k++;
}
while(Math.pow(y,y_k)< boundary){
y_k++;
}
for(int k = 2 ; k<= boundary;++k) {
for (int i = 0; i < x_k; ++i) {
for (int j = 0; j < y_k; ++j) {
if(k == (int)Math.pow(x,i)+(int)Math.pow(y,j) && !res.contains(k)){
System.out.println("----------------------------------------");
System.out.println(k +" =>" +x + "^" +i +"+"+y+ "^" +j);
res.add(k);
}
}
}
}
return res;
}
public static void main(String[] args) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x = 1 + (int) (Math.random() * 100);
int y = 1 + (int) (Math.random() * 100);
int boundary = 1 + (int) (Math.random() * 1000000);
res = find_numbers(x, y,boundary);
System.out.println("x:" + x);
System.out.println("y:" + y);
System.out.println("boundary:" + boundary);
System.out.println("Result:" + res);
}
}
Related
I'm quite new in Java and I'm getting this error I can manage to understand where it is coming from. Im doing FFT analysis and I'm getting an error:
java.lang.ArrayIndexOutOfBoundsException: 66,
at DrawingFunction.main(DrawingFunction.java:66)
at AnimationGen.begin(AnimationGen.java:54)
at FFTclass.main2(FFTclass.java:213)
at fftTry.main(fftTry.java:34)
the codes are this for the fftTry:
public static void main(String[] args) {
final String NEWLINE = "\n";
String inputFile = "C:/Users/USER/Downloads/DD.wav"; // Place the wav file in the top level directory, ie S:/input.wav
File fileLocation = new File(inputFile);
System.out.println("START");
try {
double[] complexNumber = readFully(fileLocation);
System.out.println(NEWLINE + "Read file");
double[] realPart = complexNumber;
double[] imagPart = new double[realPart.length];
System.out.println("Length = " + realPart.length);
FFTclass FFT = new FFTclass(1024);
FFT.main2(realPart,imagPart,1024);
//for (int i = 0; i < complexNumber.length; ++i) {
// System.out.println(complexNumber[i]);
//}
} catch (Exception ex) {
ex.printStackTrace();
}
}
static double[] readFully(File file) throws UnsupportedAudioFileException, IOException {
AudioInputStream in = AudioSystem.getAudioInputStream(file);
AudioFormat fmt = in.getFormat();
double sampleRate = fmt.getSampleRate();
double frameSize = fmt.getFrameSize();
double auidioDuration = fmt.getFrameRate();
double channels = fmt.getChannels();
System.out.println("File length = " + file.length() + " ");
System.out.println("Sample Rate = " + sampleRate + " per second");
System.out.println("Frame size = " + frameSize + " per second");
System.out.println("Frame rate = " + auidioDuration + " per second");
System.out.println("Channels = " + channels);
System.out.println("Length in time = " + (file.length()/frameSize * auidioDuration) + " seconds");
System.out.println("Length in time in minutes = " + (int)(file.length()/(frameSize* auidioDuration *60)) + " minutes and " + ( (file.length()/(frameSize* auidioDuration *60))- (int)(file.length()/(frameSize* auidioDuration *60)) )* 60 + " seconds");
byte[] bytes;
try {
if (fmt.getEncoding() != Encoding.PCM_SIGNED) {
throw new UnsupportedAudioFileException();
}
// read the data fully
bytes = new byte[in.available()];
in.read(bytes);
} finally {
in.close();
}
int bits = fmt.getSampleSizeInBits();
double max = Math.pow(2, bits - 1);
ByteBuffer bb = ByteBuffer.wrap(bytes);
bb.order(fmt.isBigEndian() ?
ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
double[] samples = new double[bytes.length * 8 / bits];
// convert sample-by-sample to a scale of
// -1.0 <= samples[i] < 1.0
for (int i = 0; i < samples.length; ++i) {
switch (bits) {
case 8:
samples[i] = (bb.get() / max);
break;
case 16:
samples[i] = (bb.getShort() / max);
break;
case 32:
samples[i] = (bb.getInt() / max);
break;
case 64:
samples[i] = (bb.getLong() / max);
break;
default:
throw new UnsupportedAudioFileException();
}
}
return samples;
}
For the FFTclass:
int n, m;
// Lookup tables. Only need to recompute when size of FFT changes.
double[] cos;
double[] sin;
double[] window;
public FFTclass(int n) {
this.n = n;
this.m = (int)(Math.log(n) / Math.log(2));
// Make sure n is a power of 2
if(n != (1<<m))
throw new RuntimeException("FFT length must be power of 2");
// precompute tables
cos = new double[n/2];
sin = new double[n/2];
// for(int i=0; i<n/4; i++) {
// cos[i] = Math.cos(-2*Math.PI*i/n);
// sin[n/4-i] = cos[i];
// cos[n/2-i] = -cos[i];
// sin[n/4+i] = cos[i];
// cos[n/2+i] = -cos[i];
// sin[n*3/4-i] = -cos[i];
// cos[n-i] = cos[i];
// sin[n*3/4+i] = -cos[i];
// }
for(int i=0; i<n/2; i++) {
cos[i] = Math.cos(-2*Math.PI*i/n);
sin[i] = Math.sin(-2*Math.PI*i/n);
}
makeWindow();
}
protected void makeWindow() {
// Make a blackman window:
// w(n)=0.42-0.5cos{(2*PI*n)/(N-1)}+0.08cos{(4*PI*n)/(N-1)};
window = new double[n];
for(int i = 0; i < window.length; i++)
window[i] = 0.42 - 0.5 * Math.cos(2*Math.PI*i/(n-1))
+ 0.08 * Math.cos(4*Math.PI*i/(n-1));
}
public double[] getWindow() {
return window;
}
/***************************************************************
00089 * fft.c
00090 * Douglas L. Jones
00091 * University of Illinois at Urbana-Champaign
00092 * January 19, 1992
00093 * http://cnx.rice.edu/content/m12016/latest/
00094 *
00095 * fft: in-place radix-2 DIT DFT of a complex input
00096 *
00097 * input:
00098 * n: length of FFT: must be a power of two
00099 * m: n = 2**m
00100 * input/output
00101 * x: double array of length n with real part of data
00102 * y: double array of length n with imag part of data
00103 *
00104 * Permission to copy and use this program is granted
00105 * as long as this header is included.
00106 ****************************************************************/
public void fft(double[] x, double[] y)
{
int i,j,k,n1,n2,a;
double c,s,e,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;
}
}
}
}
// Test the FFT to make sure it's working
public static void main2(double[] re, double[] im, int N) {
FFTclass fft = new FFTclass(N);
double[] window = fft.getWindow();
double[] ang;
double[] amplitude;
// Impulse
re[0] = 1; im[0] = 0;
for(int i=1; i<N; i++)
re[i] = im[i] = 0;
System.out.println("Impulse");
beforeAfter(fft, re, im);
// Nyquist
for(int i=0; i<N; i++) {
re[i] = Math.pow(-1, i);
im[i] = 0;
}
System.out.println("Nyquist");
beforeAfter(fft, re, im);
// Single sin
for(int i=0; i<N; i++) {
re[i] = Math.cos(2*Math.PI*i / N);
im[i] = 0;
}
System.out.println("Single sin");
beforeAfter(fft, re, im);
// Ramp
for(int i=0; i<N; i++) {
re[i] = i;
im[i] = 0;
}
System.out.println("Ramp");
beforeAfter(fft, re, im);
amplitude = new double[re.length];
ang = new double[re.length];
for(int i=0; i<re.length;i++)
{
amplitude[i] = Math.sqrt( (re[i]*re[i])+ (im[i]*im[i]) );
//Calculate and return the phase
// angle in degrees.
if(im[i] == 0.0 && re[i] == 0.0){ang[i] = 0.0;}
else{ang[i] = Math.atan(im[i]/re[i])*180.0/Math.PI;}
if(re[i] < 0.0 && im[i] == 0.0){ang[i] = 180.0;}
else if(re[i] < 0.0 && im[i] == -0.0){
ang[i] = -180.0;}
else if(re[i] < 0.0 && im[i] > 0.0){
ang[i] += 180.0;}
else if(re[i] < 0.0 && im[i] < 0.0){
ang[i] += -180.0;}
}
for(int i = 100500; i<100600; i++)
{
System.out.print( '\n' + "Magnitude["+i+"] = " +amplitude[i]+ ", ");
System.out.print( '\n' + "Angle phase["+i+"] = " +ang[i]+ ", ");
}
long time = System.currentTimeMillis();
double iter = 30000;
for(int i=0; i<iter; i++)
fft.fft(re,im);
time = System.currentTimeMillis() - time;
System.out.println("\n" + "Averaged " + (time/iter) + "ms per iteration");
System.out.println("Time: " + (time) + "ms");
AnimationGen animation = new AnimationGen();
animation.begin(amplitude);
}
protected static void beforeAfter(FFTclass fft, double[] re, double[] im) {
System.out.println("Before: ");
printReIm(re, im);
fft.fft(re, im);
System.out.println("After: ");
printReIm(re, im);
}
protected static void printReIm(double[] re, double[] im) {
System.out.print("Re: [");
//for(int i=0; i<re.length; i++)
System.out.println("i = " + re.length);
for(int i=100550; i<100650; i++)
System.out.print(((int)(re[i]*1000)/1000.0) + " ");
System.out.print("]\nIm: [");
//for(int i=0; i<im.length; i++)
for(int i=100550; i<100650; i++)
System.out.print(((int)(im[i]*1000)/1000.0) + " ");
System.out.println("]");
}
The AnimationGen:
public int frameWidth = 1920;
public int frameHeigth = 1080;
public int fps = 30;
public void begin(double[] magnitude)
{
int magnitudeLength = magnitude.length;
int value = (int)magnitudeLength/44100;
double [][][] magnitudesPerSecond = new double[value][fps][(int)44100/fps];
for(int i = 0; i < value;i++) {
for(int j = 0; j < fps;j++) {
for (int k = 0; k < (int)44100/fps; k++) {
int arraynumber = k + (j*fps) +(i * (int)44100/fps);
magnitudesPerSecond[i][j][k] = magnitude[arraynumber];
}
}
}
System.out.println("i = " + magnitudesPerSecond.length);
System.out.println("j = " + magnitudesPerSecond[0].length);
System.out.println("k = " + magnitudesPerSecond[0][0].length);
DrawingFunction DF = new DrawingFunction();
DF.main(value, fps, magnitudesPerSecond);
}
And the final DrawingFunction
public int second = 0;
Timer t = new Timer();
TimerTask timeTask = new TimerTask() {
#Override
public void run() {
second++;
}
};
public double addingAngle = 0;
public int frameWidth = 1920;
public int frameHeigth = 1080;
public int value;
public int fps;
public double[][][] magnitude;
double xPoint[][][];
double yPoint[][][];
public void main(int value, int fps, double[][][] magnitude) {
this.value = value;
this.fps = fps;
this.magnitude = magnitude;
///////////////////////////////////////////////////////////////////////////////////////////////////
double xPoint[][][] = new double[value][fps][64];
double yPoint[][][] = new double[value][fps][64];
for (int counter = 0; counter < value; counter++) {
for (int i = 0; i < fps; i++) {
for (int j = 0; j < (44100 / fps); j += ((44100 / fps) / 64)) {
xPoint[counter][i][j] = magnitude[counter][i][j];
for (int t = 0; t < ((44100 / fps) / 65); t++) { //64 is the number of bands taken into and only 55 from them are used
if(j+t < magnitude[0][0].length) {
xPoint[counter][i][j] += magnitude[counter][i][j + t];
}
System.out.println("Here xPoint[" +i+"]["+j+"]" + (j + t));
}
xPoint[counter][i][j] /= (int) ((44100 / fps) / 64);
}
int t = 0;
for (double angle = addingAngle; angle < 2 * Math.PI + addingAngle; angle += 2 * Math.PI / 55) {
xPoint[counter][i][t] *= Math.cos(angle); //All X points [second][frame][band]
yPoint[counter][i][t] *= Math.sin(angle); //All Y points [second][frame][band]
t++;
}
addingAngle += Math.PI / 110; //110 = 55 points * 2 so rotation is slower
}
this.xPoint = xPoint;
this.yPoint = yPoint;
// Up to here we have 64 xPoints and 64 yPoints, but only the first 55 of each are multiplied by the angle
// jl.setIcon(new ImageIcon("/images/T.png"));
}
for (int i = 0; i < 55; i++) {
System.out.println("Point[" + i + "] is: " + xPoint[0][0][i]);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
JFrame window = new JFrame();
window.add(new DrawingFunction());
window.pack();
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.setSize(frameWidth, frameHeigth);
window.setBackground(Color.blue);
window.setVisible(true);
repaint();
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.black);
g.fillRect(800, 500, 300, 300); //g.translate(frameWidth/2, frameHeigth/2);
Polygon p = new Polygon();
for (int i = 0; i < 55; i++)
p.addPoint(15 * (int) xPoint[0][0][i], 15 * (int) yPoint[0][0][i]);
g.setColor(Color.black);
g.drawPolygon(p);
g.fillRect(800, 800, 400, 400);
validate(); // So image appears even if screen is small
I know the code is long, hope its not hard to read, its the first time I make a question here
I would look at these lines here:
double xPoint[][][] = new double[value][fps][64];
//...
for (int j = 0; j < (44100 / fps); j += ((44100 / fps) / 64)) {
xPoint[counter][i][j] = magnitude[counter][i][j];
Note that the inputted fps is 30, so ((44100 / 30) / 64)) = 22.96875 (or 22 as an int). So when this loop iterates, j will be as follows:
j = 0
j = 22
j = 44
j = 66 (Array out of bounds)
The value of fps is 30 (if I'm not missing anything). 44100 / fps = 1,470. So, j goes from 0 to 1,469. But, the third dimension of your array is only 64...
double xPoint[][][] = new double[value][fps][64];
double yPoint[][][] = new double[value][fps][64];
for (int counter = 0; counter < value; counter++) {
for (int i = 0; i < fps; i++) {
for (int j = 0; j < (44100 / fps); j += ((44100 / fps) / 64)) {
xPoint[counter][i][j] = magnitude[counter][i][j];
I created a program that generates a user inputted number of pairs of points. It then goes through a bruteforce and divide and conquer methods to find the closest pair of points. The bruteforce method works perfectly. The divide and conquer method on the other hand gives me an output but it is different than the brute force distance almost 90% of the time. I can't seem to figure out why it is like this in my code. NOTE: Some of the comments in the functions are from my teacher. Also, the closest_pair function along with rec_cl_pair have been given to me by my teacher where I must use them but had to adjust to my code (they were pseudo code for most part).
My code is:
import java.util.*;
import static java.lang.Math.min;
public class ClosestPair{
private Double x;
private Double y;
private static Double minDist = Double.POSITIVE_INFINITY;
private static ClosestPair closestPair1 = new ClosestPair(0.0,0.0);
private static ClosestPair closestPair2 = new ClosestPair(0.0,0.0);
public ClosestPair(Double x, Double y){
this.x = x;
this.y = y;
}
public static void main(String[] args) {
Double rangeMin = 0.0;
Double rangeMax = 1000.0;
Random r = new Random();
Scanner scan = new Scanner(System.in);
System.out.print("\nEnter the number of two dimensional arrays: ");
int dim = scan.nextInt();
ClosestPair[] pair = new ClosestPair[dim];
ClosestPair[] pairCopy = new ClosestPair[dim];
for(int i = 0; i < dim; i++){
Double xVal = rangeMin + (rangeMax - rangeMin) * r.nextDouble();
Double yVal = rangeMin + (rangeMax - rangeMin) * r.nextDouble();
pair[i] = new ClosestPair(xVal,yVal);
//System.out.print(pair[i].x + ", " + pair[i].y + "\n");
}
/*
for(int j = 0; j < pair.length; j++){
System.out.print(pair[j].x + ", " + pair[j].y + "\n");
}
*/
pairCopy = pair;
pair = mergeSort(pair);
/*
System.out.print("\n\n\n");
for(int j = 0; j < pair.length; j++){
System.out.print(pair[j].x + ", " + pair[j].y + "\n");
}
*/
//BRUTE FORCE PRINT STATEMENTS
long startTime = System.nanoTime();
bruteForce(pair);
long endTime = System.nanoTime();
long timeSpent = endTime - startTime;
System.out.print("\nMin Distance = " + minDist);
System.out.print("\n(x1,y1) = " + closestPair1.x + ", " + closestPair1.y);
System.out.print("\n(x2,y2) = " + closestPair2.x + ", " + closestPair2.y);
System.out.print("\nTime: " + timeSpent + "\n\n");
minDist = 0.0;
//CONQUER DIVIDE PRINT STATEMENTS
startTime = System.nanoTime();
minDist = closest_pair(pairCopy);
endTime = System.nanoTime();
timeSpent = endTime - startTime;
System.out.print("Min Distance = " + minDist);
System.out.print("\nTime: " + timeSpent);
scan.close();
}
private static void bruteForce(ClosestPair[] pair) {
for(int i = 1; i < pair.length - 1; i++){
for(int j = i + 1; j < pair.length; j++){
ClosestPair p = new ClosestPair(pair[i].x,pair[i].y);
//System.out.print("\np:" + pair[i].x + ", " + pair[i].y);
ClosestPair q = new ClosestPair(pair[j].x,pair[j].y);
//System.out.print("\nq: " + pair[j].x + ", " + pair[j].y);
if(getDistance(p, q) < minDist){
minDist = getDistance(p, q);
closestPair1.x = p.x;
closestPair1.y = p.y;
closestPair2.x = q.x;
closestPair2.y = q.y;
}
}
}
}
private static Double getDistance(ClosestPair p1, ClosestPair p2) {
double xdist = p2.x - p1.x;
double ydist = p2.y - p1.y;
return Math.hypot(xdist, ydist);
}
static ClosestPair[] mergeSort(ClosestPair[] a) {
if (a.length > 1) {
int q = a.length/2;
ClosestPair[] leftArray = Arrays.copyOfRange(a, 0, q);
ClosestPair[] rightArray = Arrays.copyOfRange(a,q,a.length);
mergeSort(leftArray);
mergeSort(rightArray);
a = merge(a,leftArray,rightArray);
}
return a;
}
static ClosestPair[] merge(ClosestPair[] a, ClosestPair[] l, ClosestPair[] r) {
int totElem = l.length + r.length;
//int[] a = new int[totElem];
int i,li,ri;
i = li = ri = 0;
while ( i < totElem) {
if ((li < l.length) && (ri<r.length)) {
if (l[li].x < r[ri].x) {
a[i] = l[li];
i++;
li++;
}
else {
a[i] = r[ri];
i++;
ri++;
}
}
else {
if (li >= l.length) {
while (ri < r.length) {
a[i] = r[ri];
i++;
ri++;
}
}
if (ri >= r.length) {
while (li < l.length) {
a[i] = l[li];
li++;
i++;
}
}
}
}
return a;
}
//START OF CONQUER DIVIDE SECTOIN
static double closest_pair(ClosestPair[] p){
int n = p.length - 1;
p = mergeSortDC(p, 0, n); // sort all n points by x-coordinate
return rec_cl_pair(p, 0, n);
}
static double rec_cl_pair(ClosestPair[] p, int i, int j){ // finds closest pair between points in p[i..j]
// assumes input is sorted by x-coordinate
// at termination, input is sorted by y-coordinate
// i is the left index of the subarray, j is the right index
if (j - i < 3){ // at most 3 points in p[i..j]
p = mergeSortDC (p, i, j); // sort p[i..j] by y-coordinate
double delta = getDistance(p[i], p[i+1]);
if (j - i == 1) { // two points
minDist = delta;
return delta;
}
else{
double min1 = min(getDistance(p[i+1], p[i+2]), getDistance(p[i], p[i+2]));
minDist = min(delta,min1);
return minDist;
}
}
int m = (i + j)/2;
double line = p[m].x;
double deltaL = rec_cl_pair(p, i, m); // p[i..m] is sorted by y-coordinate
double deltaR = rec_cl_pair(p, m+1, j); // p[m+1..j] is sorted by y-coordinate
double delta = min(deltaL, deltaR);
p = mergeDC(p, i, m, j); // p[i..j] is now sorted by y-coordinate
// Of points in p[i..j], find points in vertical strip of width 2*delta,
// centered at line (middle of x-values), and store in array v
int t = 0;
ClosestPair[] v = new ClosestPair[j+1];
for(int k = i; k < j; k++){
if ((p[k].x > line - delta) && (p[k].x < line + delta)){
t = t + 1;
v[t] = p[k];
}
}
// Find closest pairs among points in array v. NOTE: Cool math shows
// there are at most 8 points in the strip at distance < delta. Thus,
// in the loops below, each point is compared to at most 7 other points.
for(int k = 1;k < t-1; k++){
for(int s = k+1; k < min(t,k+7); s++){ // inner loop iterates <= 7 times
delta = min(delta, getDistance(v[k],v[s]));
minDist = delta;
return delta;
}
}
return minDist;
}
private static ClosestPair[] mergeSortDC(ClosestPair[] p, int low, int high) {
// check if low is smaller then high, if not then the array is sorted
if (low < high) {
// Get the index of the element which is in the middle
int middle = low + (high - low) / 2;
// Sort the left side of the array
mergeSortDC(p, low, middle);
// Sort the right side of the array
mergeSortDC(p, middle + 1, high);
// Combine them both
p = mergeDC(p, low, middle, high);
}
return p;
}
private static ClosestPair[] mergeDC(ClosestPair[] p, int low, int middle, int high) {
ClosestPair[] helper = new ClosestPair[p.length];
// Copy both parts into the helper array
for (int i = low; i <= high; i++) {
helper[i] = p[i];
}
int i = low;
int j = middle + 1;
int k = low;
// Copy the smallest values from either the left or the right side back
// to the original array
while (i <= middle && j <= high) {
if (helper[i].x <= helper[j].x) {
p[k] = helper[i];
i++;
} else {
p[k] = helper[j];
j++;
}
k++;
}
// Copy the rest of the left side of the array into the target array
while (i <= middle) {
p[k] = helper[i];
k++;
i++;
}
return p;
}
}
An example of output is:
Enter the number of two dimensional arrays: 50
Min Distance = 19.014027210555614
(x1,y1) = 76.99595098629398, 600.1657767818473
(x2,y2) = 87.04091889578226, 616.3098732403395
Time: 3852815
Min Distance = 29.457199999686082
Time: 414081
The first min distance is the bruteforce result. The second is the divide and conquer result
I'm trying to write a code that multiplies two strings of integers. I'm not too sure where it's going wrong... It works for some numbers, but is horribly wrong for others. I'm not asking for a full solution, but just a hint (I seriously appreciate any help possible) as to where I'm making the obviously silly mistake. Thanks in advance.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Please enter a big integer. ");
String t = scan.nextLine();
System.out.print("And another. ");
String s = scan.nextLine();
BigInt a = new BigInt(t);
BigInt b = new BigInt(s);
System.out.println(a + " + " + b + " = " + a.add(b));
System.out.println(a + " - " + b + " = " + a.sub(b));
System.out.println(a + " * " + b + " = " + a.mul(b));
System.out.println(a + " / " + b + " = " + a.div(b));
}
}
class BigInt {
public BigInt() {
n = new int[1];
}
public BigInt(String s) {
n = new int[s.length()];
for (int i = 0; i < n.length; ++i) {
n[n.length - i - 1] = s.charAt(i) - '0' ;
}
}
private BigInt(int[] n) {
this.n = new int[n.length];
for (int i = 0; i < n.length; ++i) {
this.n[i] = n[i];
}
}
public String toString() {
String s = "";
for (int i : n) {
s = i + s;
}
return s;
}
public BigInt mul(BigInt o) {
int carry = 0;
int s = 0;
int digit;
int subtotal = 0;
int total = 0;
int max = n.length > o.n.length ? n.length : o.n.length;
int[] result = new int[n.length + o.n.length];
for (int i = 0; i < o.n.length; ++i) {
int bottom = i <= o.n.length ? o.n[i] : 0;
for (s = 0; s <= n.length; ++s){
int top = s < n.length ? n[s] : 0;
int prod = (top * bottom + carry);
if (s == (max-1)) {
total = Integer.valueOf((String.valueOf(prod) + String.valueOf(subtotal)));
carry = 0;
digit = 0;
subtotal = 0;
break;
}
if (prod < 10) {
digit = prod;
subtotal += digit;
carry = 0;
}
if (prod >= 10); {
digit = prod % 10;
carry = prod / 10;
subtotal += digit;
}
}
result[i] = total;
}
return new BigInt(trim(result));
}
private int[] trim(int[] nums) {
int size = nums.length;
for (int i = nums.length - 1; i > 0; --i) {
if (nums[i] != 0) {
break;
}
--size;
}
int[] res = new int[size];
for (int i = 0; i < size; ++i) {
res[i] = nums[i];
}
return res;
}
private int[] n;
}
A quick test using:
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 10; y++) {
System.out.println(x + " * " + y + " = " + new BigInt(Integer.toString(x)).mul(new BigInt(Integer.toString(y))));
}
}
demonstrates that somehow your multiply of x * y is actually multiplying by 10x * y. That should give you a clear hint to the problem.
Say I have an array of 5 strings and that related to that array is 3 arrays of integers all of the same size. e.g.`
String a[] = new String[5]
int x[] = new int[5]
int y[] = new int[5]
int z[] = new int[5]
so that a[0],x[0],y[0],z[0] are all related to the same thing.
I want to find out which index(es) in x[] hold the highest number. If more than one those has the same highest number then which of those has the highest number in y[] and if there is more than one with the same highest number which one would have the highest in z[](Its safe to assume that none would have the same max value in z[]
I've tried to explain as best I can..
This is the best if got it only checks the first 2 conditions
for(int i=0;i<a.length;i++)
{
if(x[i]>=maximum){
if(x[i]==maximum)
{
if(y[i]>=maximum)
{
maximum=x[i];
winner=a[i];
maximum=y[i];
}
}
else
{
maximum=x[i];
winner=teams[i];
maximum=y[i];
}
}
So this is my new code
static int compareValues(){
for (int i=0; i<a.length; i++){
int max =0;
int diff = x[i] - x[max];
if (diff == 0){
diff = y[i] - y[max];
}
if (diff == 0){
diff = z[i] - z[max];
}
if (diff > 0){
max = i
}
}
return max;
}
If the String[n] is related to the int[n]s for each n then really you should compose them properly, make them Comparable and sort them.
class Thing implements Comparable<Thing> {
final String a;
final int x;
final int y;
final int z;
public Thing(String a, int x, int y, int z) {
this.a = a;
this.x = x;
this.y = y;
this.z = z;
}
#Override
public int compareTo(Thing o) {
int diff = o.x - x;
if (diff == 0) {
diff = o.y - y;
}
if (diff == 0) {
diff = o.z - z;
}
return diff;
}
#Override
public String toString() {
return "{" + a + "," + x + "," + y + "," + z + "}";
}
}
public static int max(Thing[] things) {
// NB - This should really call compareTo.
int max = 0;
for (int i = 1; i < things.length; i++) {
int diff = things[i].x - things[max].x;
if (diff == 0) {
diff = things[i].y - things[max].y;
}
if (diff == 0) {
diff = things[i].z - things[max].z;
}
if (diff > 0) {
// Higher
max = i;
}
}
return max;
}
public void test() {
Thing[] things = new Thing[6];
things[0] = new Thing("Hello", 1, 2, 3);
things[1] = new Thing("There", 1, 2, 4);
things[2] = new Thing("Everyone", 0, 2, 3);
things[3] = new Thing("How", 9, 0, 3);
things[4] = new Thing("Are", 8, 9, 3);
things[5] = new Thing("You", 7, 2, 3);
System.out.println("Before: " + Arrays.toString(things));
System.out.println("Max: " + things[max(things)]);
Arrays.sort(things);
System.out.println("Sorted: " + Arrays.toString(things));
}
This solution might be easier to understand:
static String compareValues() {
// find the maximum in x
int xMax = Integer.MIN_VALUE;
for (int i = 0; i < 5; i++) {
if (x[i] > xMax) {
xMax = x[i];
}
}
// find the maximum in y, but limited to the positions where x is maximal according to the calculation above
int yMax = Integer.MIN_VALUE;
for (int i = 0; i < 5; i++) {
if (x[i] == xMax && y[i] > yMax) {
yMax = y[i];
}
}
// find the maximum in z, but limited to the positions where y is maximal according to the calculation above
int zMax = Integer.MIN_VALUE;
int iMax = 0;
for (int i = 0; i < 5; i++) {
if (y[i] == yMax && z[i] > zMax) {
zMax = z[i];
iMax = i; // record the maximum position
}
}
return a[iMax];
}
I did not test the code, but I think that it should work.
I have such a cycle (it is piece of my other code):
for (int i = 2; i < 257; i = i * 2) {
V -= i + 0;
System.out.println("Suma: " +V+ " atemus: "+i);
///////////////////
int X [][] = new int [8][16]; //multi array where i need to put "i" values
}
and how you see in code have i muti array:
int X [][] = new int [8][16];
How put values of i in array and print it into a screen?
ok i put my whole code:
import java.util.Scanner;
public class IV_darbas {
public static void main(String[] arguments) {
int r, H, R, V, x, k, z;
Scanner ivestis = new Scanner(System.in);
boolean pabaiga = false;
while (!pabaiga) {
System.out.println("");
System.out.println("Si programa leis skaiciuoti turi");
System.out.println("Jei noresi testi spausk bet kuri klavisa");
System.out.println("Kai noresi baigti ivesk zodi: pabaiga ");
String first = "testi";
// Ivedi "R" reiksme
Scanner one = new Scanner(System.in);
System.out.println("Ivesk reiksme: R");
R = one.nextInt();
// Ivedi "H" reiksme
Scanner two = new Scanner(System.in);
System.out.println("Ivesk reiksme: H");
H = two.nextInt();
// Ivedi "R" reiksme
Scanner three = new Scanner(System.in);
System.out.println("Ivesk reiksme: r");
r = three.nextInt();
V = (int) ((Math.PI * Math.pow(H, 4) * (Math.pow(R, 2)
+ Math.pow(r, 2) + Math.pow(r, 5) * Math.pow(r, 3))) / 3);
System.out.println("Tavo gautas turis: " + V);
z = V * (-1);
System.out.println("Tavo gautas turis(su priesingu zenklu):" + z);
// Ivedamas papildomas skaicius
Scanner four = new Scanner(System.in);
System.out.println("Ivesk dar viena skaiciu: ");
x = four.nextInt();
k = x * z;
// salygos if sakinys
System.out.println("Pakeisto ir papildomo skaciaus sandauga: " + k);
if (k > 0) {
System.out.println("gautas skaicius " + k + " yra teigiamas");
} else if (k < 0) {
System.out.println("gautas skaicius " + k + " yra neigiamas");
} else if (k == 0) {
System.out.println("gautas skaicius " + k + " yra neutralus");
}
System.out.println("");
System.out.println("Sumavimas. Prie gauto rezultato: " + V);
for (int i=2; i<257; i=i*2 ){
V += i+0;
System.out.println("Suma: " +V+ " pridejus: "+i);
}
V = (int) ((Math.PI * Math.pow(H, 4) * (Math.pow(R, 2)
+ Math.pow(r, 2) + Math.pow(r, 5) * Math.pow(r, 3))) / 3);
System.out.println("");
System.out.println("Atimtis. Prie gauto rezultato: " + V);
for (int i=2; i<257; i=i*2 ){
V -= i+0;
System.out.println("Suma: " +V+ " atemus: "+i);
///////////////////
int X [][] = new int [8][16];
}
System.out.println("");
System.out.println("Ar testi? (n/y)");
first = ivestis.next();
if (first.equalsIgnoreCase("Pabaiga")) {
System.out.println("Darbas baigtas!");
break;
}
}
}
}
It is very unclear what you are trying to do and here is an example of what you might want to do.
// declared before any loop so it is in scope after the loop
int[][] values = new int[8][16];
int i = 1;
for(int x = 0; x < values.length; x++) {
for(int y = 0; y < values[x].length; y++) {
values[x][y] = i;
i += 2;
}
}
// to print the values
for(int x = 0; x < values.length; x++) {
for(int y = 0; y < values[x].length; y++) {
System.out.print(values[x][y] + " ");
}
System.out.println();
}
If you're asking just how to add something to an array it goes like this:
X[n] = i;
where n is an index in the array. But as someone already said you need to declare your array outside of the loop, otherwise it won't be accessible.