I want to convert this method into one loop, any kind of loop is fine i find it hard to convert from recursion.
public class Problem5
{
public double getRoot(double a, double b)
{
double x = (a + b)/2;
if (b - a <= 0.00)
return x;
double y = getValue(x);
if(y < 0)
return getRoot(x, b);
else
return getRoot(a, x);
}
public double getRoot(double a, double b) {
while (true) {
double x = (a + b)/2;
if (b - a <= 0.00)
return x;
double y = getValue(x);
if(y < 0)
a = x;
else
b = x;
}
throw new AssertionError("should not happen");
}
Related
public class Pow {
public double getAnswer(double a, double b) {
double b2 = 0;
if (b > 0) {
for (int i = 1; i < b; i++) {
a = a * a;
}
return a;
} else if (b < 0) {
int c = 0;
while (c > b) {
a = a * a;
c--;
}
b2 = 1 / a;
}
return b2;
}
}
I need the second part of my method to return the value of a negative power(i.e. 5^-2 = .04), but the output is always 0. The first part of the method works fine from what I have tested. I do have the last curly braces but they just wouldn't fit in the text box on here. Any help/suggestions would be much appreciated!
Running your code does not produce 0 as a result, but there is a bug.
a = a * a squares the number every iteration, so an will be calculated as: a2n-1.
Try accumulating the multiplication in a different variable:
double b2 = 0;
double result = 1;
if (b > 0) {
for (int i = 1; i <= b; i++) {
result *= a;
}
return result;
} else if (b < 0) {
int c = 0;
while (c > b) {
result *= a;
c--;
}
b2 = 1 / result;
}
return b2;
public class Pow {
public double getAnswer(double a, double b) {
double b2 = 0;
if (b > 0) {
for (int i = 1; i < b; i++) {
a = a * a;
}
return a;
} else if (b < 0) {
return getAnswer(a, -b);
}
return 1; // b is 0
}
Your algorithm for (b < 0) was wrong. If b < 0, the calculation is 1 / a^(-b).
Why your parameter b is of type double? What if b is 2.5? I suggest to change the type of b to int or you have to change your algorithm.
As Bohemian♦ said
a = a * a;
squares a each time.
What we want is for a (the base) to be multiplied by itself b (the power) times.
Since the only difference between a to the power of b and a to the power of (-b) is that the latter is the 1 / the former, we can use quite nearly the same code for both negative and positive exponents.
Code:
public double getAnswer(double a, double b) {//a is the base, b is the power
double a2 = 1;
double b2 = 0;
if (b > 0) {//for positive powers
for (int i = 0; i < b; i++) {//a needs to be multiplied by itself (b) times
a2 = a2 * a;
}
return a2;
}
else if (b < 0) {//for negative powers
for (int i = 0; i < -b; i++) {//a still needs to be multiplied by itself (-b) times, but since b is negative, we increment up to the opposite of b
a2 = a2 * a;
}
return 1 / a2;//finally, since the power (b) is negative, we need to return 1 / (a2)
}
}
So i have a little problem with reducing a negative fraction
This is my reduce code
private void reduce() {
int g = Helper.gcd(this.num, this.den);
num /= g;
den /= g;
}
For example:
8/64 gives 1/8
But giving -8/64 let's the program crash
This is my gcd code
public static int gcd(int a, int b) {
while (a != b) {
if (a > b) {
a -= b;
} else {
b -= a;
}
}
return a;
}
You need to extract the sign first.
private void reduce() {
boolean neg = (num < 0) != (den < 0);
num = Math.abs(num);
den = Math.abs(den);
// obtain the GCD of the non-negative values.
int g = Helper.gcd(num, den);
num /= g;
den /= g;
if (neg) num *= -1;
}
Your gcd method only works for positive numbers. Negative numbers and zero need to be handled separately.
public static int gcd(int a, int b) {
a = Math.abs(a);
b = Math.abs(b);
if (a == 0) {
if (b == 0)
throw new IllegalArgumentException();
return b;
}
if (b == 0)
return a;
// The rest is just your code, unchanged.
while (a != b) {
if (a > b) {
a -= b;
} else {
b -= a;
}
}
return a;
}
I'm making a simple test in java, (i'm a begineer) and i was trying to make a program that calculates the discriminate of a second degree equation and displays the results, but when i change the sign of nom1 and nom2, the program doesn't displays any result, i've made some tests and i'm sure that the problem is there but i don't know how to resolve it.
Any help is welcome.
Here is my code:
public class test {
public static void main(String[] args) {
double a = 2;
double b = 5;
double c = 3;
double delta = b*b - 4 * a * c;
double den = 2 * a;
if(delta == 0){
double nom = b;
double pgcd = pgcd(nom, den);
double x0nom = nom/pgcd;
double x0den = den/pgcd;
System.out.println("x0 = "+String.valueOf(x0nom)+" / "+String.valueOf(x0den));
}else if(delta > 0){
// x1:
double nom1 = -b + Math.sqrt(delta);
double pgcd1 = pgcd(nom1, den);
int x1nom = (int) (nom1 / pgcd1);
int x1den = (int) (den / pgcd1);
// x2:
double nom2 = -b - Math.sqrt(delta);
double pgcd2 = pgcd(nom2, den);
int x2nom = (int) (nom2 / pgcd2);
int x2den = (int) (den / pgcd2);
System.out.println("pgcd = "+String.valueOf(pgcd1)+" "+String.valueOf(pgcd2));
System.out.println("x1 = "+String.valueOf(x1nom)+" / "+String.valueOf(x1den));
System.out.println("x2 = "+String.valueOf(x2nom)+" / "+String.valueOf(x2den));
}else if(delta < 0){
}
}
public static double pgcd(double a, double b) {
while (a != b) {
if (a < b){
b = b - a;
}else{
a = a - b;
}
}
return a;
}
}
Use BigInteger's gcd method
public static double pgcd(double a, double b) {
return (BigInteger.valueOf((long) a).gcd(BigInteger.valueOf((long) b)).intValue());
}
Suppose you have an array of Points on a 2D plane. Point being defined as such:
class Point {
public int x;
public int y;
Point(int _x, int _y) { x = _x; y = _y; }
}
How could I find the maximum number of points lying on the same straight line in java?
For each point in the array, calculate the angle between this point and other points. Counting the number of those with the same angle using a hashMap. Expected time O(n^2)
Pseudo code
int result = 0;
for(int i = 0; i < data.length; i++){
HashMap<Double, Integer> map = new HashMap();
for(int j = 0; j < data.length; j++){
if(i == j)
continue;
double angle = calculateAngle(data[i], data[j]);
if(map.containsKey(slope)){
map.put(angle, map.get(slope) + 1);
}else{
map.put(angle, 1);
}
result = max(result, map.get(slope));
}
}
Note: As mention in NiklasB 's comment, using double will cause some problems with precision, especially when we need to compare those floating values. We can avoid that by using the Rational class suggested by NiklasB. (Or less precise, using this)
Here is a solution in Java using precise arithmetic:
import java.util.List;
import java.util.Map;
import java.util.HashMap;
public class Solver {
public int maxPointsOnLine(List<Point> points) {
int ans = 0;
Map<Line, Integer> lines = new HashMap<Line, Integer>();
for (Point a : points) {
int max = 0;
int same = 0;
lines.clear();
for (Point b : points) {
if (a.x == b.x && a.y == b.y) {
++same;
} else {
Line line = new Line(b.x - a.x, b.y - a.y);
Integer count = lines.get(line);
if (count == null) {
count = 0;
}
++count;
lines.put(line, count);
max = Math.max(max, count);
}
}
ans = Math.max(ans, same + max);
}
return ans;
}
static class Line {
final int dx;
final int dy;
Line(int dx, int dy) {
if (dy == 0) {
dx = Math.abs(dx);
}
else if (dy < 0) {
dx = -dx;
dy = -dy;
}
int gcd = gcd(Math.abs(dx), dy);
dx /= gcd;
dy /= gcd;
this.dx = dx;
this.dy = dy;
}
#Override
public boolean equals(Object other) {
if (!(other instanceof Line)) {
return false;
}
Line another = (Line)other;
return dx == another.dy && dy == another.dy;
}
#Override
public int hashCode() {
return 31 * dx + dy;
}
}
static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
/**
* Definition for a point.
* struct Point {
* int x;
* int y;
* Point() : x(0), y(0) {}
* Point(int a, int b) : x(a), y(b) {}
* };
*/
class Solution {
public:
int maxPoints(vector<Point> &points) {
int n = points.size(); //number of the points
if (n<=2){return n;}
vector<double> k; //vector to store the slops for one point with all the other points
int res = 0;
for (int i=0;i<n;i++){ // for each point in the 2d plane
k.clear();
int dup = 1; // number of the duplicates with currrent point
for (int j=0;j<n;j++){
if (i!=j){ // for every other point
if (points[i].x-points[j].x==0){ // if the slope is a vertical line
if (points[i].y-points[j].y==0){ // if the point j is the same as point i
dup++;
}else{
k.push_back(99999); //store the vertical line to a specific slope
}
}else{ // if it is the regular slop between point i and j
k.push_back(10000*(points[i].y-points[j].y)/(points[i].x-points[j].x)); // store the slope
}
}
}
sort(k.begin(),k.end()); //sort the slopes for counting
int pp = 1; //number of points in the same line of the point i
if (k.size()==0){pp=0;}
for (int jj=1;jj<k.size();jj++){ //count pp
if (k[jj]==k[jj-1]){
pp++;
}else{
if (pp+dup>res){res=pp+dup;} // res = pp + the number of duplicates
pp = 1;
}
}
if (pp+dup>res){res = pp+dup;}
}
return res;
}
};
public class MultiplyViaRecursion{
public static void main(String[] args){
System.out.println("8 * 9 == " + multiply(8, 9));
System.out.println("6 * 0 == " + multiply(6, 0));
System.out.println("0 * 6 == " + multiply(0, 6));
System.out.println("7 * -6 == " + multiply(7, -6));
}
public static int multiply(int x, int y){
int result = 0;
if(y > 0)
return result = (x + multiply(x, (y-1)));
if(y == 0)
return result;
if(y < 0)
return result = -multiply(x, -y);
return result;
}
}
My question is very simple and basic, why after each "if" the "return" still cannot pass the compilation, error shows missing return.
To put it simply: the Java compiler isn't that smart. It can't deduce that one of your three if statements must evaluate to true. And since the compiler believes there is a chance all the if conditions can fail, it thinks it's possible to go beyond the if blocks, at which point there is no return statement.
Instead, try using an if else block, like so.
public static int multiply(int x, int y) {
int result = 0;
if (y > 0)
return result = (x + multiply(x, (y - 1)));
else if (y == 0)
return result;
else
return result = -multiply(x, -y);
}
Because the compiler cannot guess that your three IFs cover all the cases.
If you want to simplify the code, you can remove the last IF that is unnecessary :
public static int multiply(int x, int y){
int result = 0;
if(y > 0)
return result = (x + multiply(x, (y-1)));
if(y == 0)
return result;
return result = -multiply(x, -y);
}
By the way, you can also remove the result variable :
public static int multiply(int x, int y){
if(y > 0)
return (x + multiply(x, (y-1)));
if(y == 0)
return 0;
return -multiply(x, -y);
}