In Python there is an efficient for .. else loop implementation described
here
Example code:
for x in range(2, n):
if n % x == 0:
print n, 'equals', x, '*', n/x
break
else:
# loop fell through without finding a factor
print n, 'is a prime number'
In Java I need to write more code to achieve the same behavior:
finishedForLoop = true;
for (int x : rangeListOfIntegers){
if (n % x == 0)
{
//syso: Some printing here
finishedForLoop = false
break;
}
}
if (finishedForLoop == true){
//syso: Some printing here
}
Is there any better implementation similar to Python for .. else loop in Java?
It's done like this:
class A {
public static void main(String[] args) {
int n = 13;
found: {
for (int x : new int[]{2,3,4,5,6,7,8,9,10,11,12})
if (n % x == 0) {
System.out.println("" + n + " equals " + x + "*" + (n/x));
break found;
}
System.out.println("" + n + " is a prime number");
}
}
}
$ javac A.java && java A
13 is a prime number
When I need to do something like this, if no extra information is needed, I typically try to break it out into a separate method - which can then return true/false or alternatively either the value found, or null if it's not found. It doesn't always work - it's very context-specific - but it's something worth trying.
Then you can just write:
for (...) {
if (...) {
return separateMethod();
}
}
return null; // Or false, or whatever
No. That's the simplest. It's not that complicated, it's just syntax.
Since java8 there is a way to write this with "nearly no" code:
if(IntStream.range(2, n).noneMatch(x -> n % x == 0)) {
System.out.println(n + " is a prime number");
}
BUT: this would be less efficient than the classical looping-with-break-and-flag method.
No, there is no mechanism like this in Java
Related
I'm really new to coding and just got assigned my first coding homework involving methods and returns. I managed to struggle through and end up with this, which I'm pretty proud of, but I'm not quite sure it's right. Along with that, my return statements are all on the same lines instead of formatted how my teacher says they should be ("n is a perfect number", then the line below says "factors: x y z", repeated for each perfect number. Below are the exact instructions plus what it outputs. Anything will help!
Write a method (also known as functions in C++) named isPerfect that takes in one parameter named number, and return a String containing the factors for the number that totals up to the number if the number is a perfect number. If the number is not a perfect number, have the method return a null string (do this with a simple: return null; statement).
Utilize this isPerfect method in a program that prompts the user for a maximum integer, so the program can display all perfect numbers from 2 to the maximum integer
286 is perfect.Factors: 1 2 3 1 2 4 7 14
It should be
6 is perfect
Factors: 1 2 3
28 is perfect
Factors: 1 2 4 7 14
public class NewClass {
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
System.out.print("Enter max number: ") ;
int max = input.nextInt() ;
String result = isPerfect(max) ;
System.out.print(result) ;
}
public static String isPerfect(int number) {
String factors = "Factors: " ;
String perfect = " is perfect." ;
for (int test = 1; number >= test; test++) {
int sum = 0 ;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
sum += counter ;
}
}
if (sum == test) {
perfect = test + perfect ;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
factors += counter + " " ;
}
}
}
}
return perfect + factors ;
}
}
Couple of things you could do:
Firstly, you do not need two loops to do this. You can run one loop till number and keep checking if it's divisible by the iterating variable. If it is, then add it to a variable called sum.
Example:
.
factors = []; //this can be a new array or string, choice is yours
sum=0;
for(int i=1; i<number; i++){
if(number % i == 0){
sum += i;
add the value i to factors variable.
}
}
after this loop completes, check if sum == number, the if block to return the output with factors, and else block to return the output without factors or factors = null(like in the problem statement)
In your return answer add a newline character between perfect and the factors to make it look like the teacher's output.
You can try the solution below:
public String isPerfect(int number) {
StringBuilder factors = new StringBuilder("Factors: ");
StringBuilder perfect = new StringBuilder(" is perfect.");
int sum = 0;
for (int i = 1; i < number; i++) {
if (number % i == 0) {
sum += i;
factors.append(" " + i);
}
}
if (sum == number) {
return number + "" + perfect.append(" \n" + factors);
}
return number + " is not perfect";
}
Keep separate variables for your template bits for the output and the actual output that you are constructing. So I suggest that you don’t alter factors and perfect and instead declare one more variable:
String result = "";
Now when you’ve found a perfect number, add to the result like this:
result += test + perfect + '\n' + factors;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
result += counter + " ";
}
}
result += '\n';
I have also inserted some line breaks, '\n'. Then of course return the result from your method:
return result;
With these changes your method returns:
6 is perfect.
Factors: 1 2 3
28 is perfect.
Factors: 1 2 4 7 14
Other tips
While your program gives the correct output, your method doesn’t follow the specs in the assignment. It was supposed to check only one number for perfectness. Only your main program should iterate over numbers to find all perfect numbers up to the max.
You’ve got your condition turned in an unusual way here, which makes it hard for me to read:
for (int test = 1; number >= test; test++) {
Prefer
for (int test = 1; test <= number; test++) {
For building strings piecewise learn to use a StringBuffer or StringBuilder.
Link
Java StringBuilder class on Javapoint Tutorials, with examples.
How can I optimize this code.
I want to reduce lines of code.
public class CoolDude {
public static void main(String[] args) {
for(int i = 100; i <= 500; ++i) {
if(i%5 == 0 && i%11 == 0) {
System.out.print("Cool Dude- ");
System.out.print(i + "\n");
} else if (i%5 == 0) {
System.out.print("Cool - ");
System.out.print(i + "\n");
} else if (i%11 == 0) {
System.out.print("Dude - ");
System.out.print(i + "\n");
}
}
}
}
Is there any way ?
While Stephen M Irving's answer is pretty spot on and corrects all the beliefs found in your question, this still answers your question, trying to minimize the number of statements.
public class CoolDude {
public static void main(String[] args) {
for (int i = 100; i <= 500; i++)
if (i % 5 == 0 || i % 11 == 0) // This is the condition where we decide to print something
System.out.printf("%s%s- %d%n", i % 5 == 0 ? "Cool " : "", i % 11 == 0 ? "Dude " : "", i);
}
}
However, this code duplicates one of the most expensive part: the modulo. Also, this solution is not readable !
When trying to figure solutions is useful to try several KPI and then find the best to optimize. In this case, you wanted to optimize the number of lines, it's definitely not the best as you can see above. If anything try first to get a working solution then a readable one and finally an optimized one where you document why it's optimized so that the readability is maintained.
Here, for instance, is the most optimized version I could come up with. It definitely contains more lines, but also is definitely faster, since I skip all invalid numbers and never do a modulo (only two divisions and two multiplications for the whole program).
public class CoolDude {
public static void main(String[] args) {
final int min = 100;
final int max = 500;
for (int i5 = nextMultiple(min, 5), i11 = nextMultiple(min, 11); i5 <= max || i11 <= max; ) {
if (i5 < i11) {
System.out.printf("Cool - %d%n", i5);
i5 += 5;
} else if (i11 < i5) {
System.out.printf("Dude - %d%n", i11);
i11 += 11;
} else { // i5 == i11
System.out.printf("Cool Dude - %d%n", i5);
i5 += 5;
i11 += 11;
}
}
}
static int nextMultiple(int number, int divisor) {
int roundToLower = (number - 1) / divisor * divisor;
return roundToLower + divisor;
}
}
You could restructure your decision tree such that there will only ever have to be 2 checks (each with 1 operation and 1 comparison) against the number in the loop. Currently, your decision tree requires 2 operations and 2 comparisons in the best case (i is divisible by both 5 and 11) and 4 operations and 4 comparisons in the worst case (i is not divisible by either 5 or 11), but we can reduce that to always be just 2 comparisons and 2 operations, which will result in a more performant loop. In this way, i is only ever tested for divisibility against 5 and 11 one time for each number, so only 2 operations and 2 comparisons will need to be done no matter what the stage of the loop. This is the sort of optimization you should be looking at when trying to optimize a loop.
I also made your print method calls a printf call instead, reducing two print statements into 1. Here is a printf cheat sheet that you can use if you are unfamiliar with it.
Now, doing all this only reduced the size of your code by 1 line, and while I am sure that could be reduced further with some clever use of ternary operators or other methods, as a general rule, measuring code quality by number of lines is a terrible metric, and should never be used, particularly when we are talking about a compiled language like Java. There are a lot of things I could do to the code below that would reduce the line count at the expense of readability and/or performance, but there is no real point to that outside of competitions between programmers, like code golf (but even with that you are competing for the lowest character count, not line count).
Instead of shooting for shorter code, you should instead be striving for the best Big-O notation complexity so that your code is more performant, and fewer lines of code does not necessarily correlate with performance.
public class CoolDude {
public static void main(String[] args) {
for (int i = 100; i <= 500; ++i) {
if (i % 5 == 0) {
if (i % 11 == 0) {
System.out.printf("Cool Dude - %d\n", i);
} else {
System.out.printf("Cool - %d\n", i);
}
} else if (i % 11 == 0) {
System.out.printf("Dude - %d\n", i);
}
}
}
}
IntStream.rangeClosed(100,500).forEach(i->{
if(i%5 == 0 && i%11 == 0) {
System.out.println("Cool Dude - "+i );
} else if (i%5 == 0) {
System.out.println("Cool - "+i );
} else if (i%11 == 0) {
System.out.println("Dude - "+i );
}
});
The below should reduce lines of code, though it does not appear to run faster. It also corrects spacing around the hyphen and perhaps simplifies the logic.
public class CoolDude {
public static void main(String args[]) {
for (int i = 100; i <= 500; ++i) {
StringBuilder coolDude = new StringBuilder(15); //15 chars max "Cool Dude - 495"
if (i % 5 == 0) {
coolDude.append("Cool ".toCharArray());
}
if (i % 11 == 0) {
coolDude.append("Dude ".toCharArray());
}
if (coolDude.length() > 0) {
System.out.println(coolDude.append(("- " + i).toCharArray()));
}
}
}
}
REVISION:
My point was that it was possible to take advantage of being able to do each mod calculation only once each time through the loop. That got lost in trying to save time with StringBuilders and a single line (which, as others pointed out, isn't a worthy goal). I clarified by using print and println instead.
public class CoolDude {
public static void main(String args[]) {
boolean printed = false;
for (int i = 100; i <= 500; ++i, printed = false) {
if (i % 5 == 0) {
System.out.print("Cool ");
printed = true;
}
if (i % 11 == 0) {
System.out.print("Dude ");
printed = true;
}
if (printed) {
System.out.println("- " + i);
}
}
}
}
I have given Fibonacci digits only , i have to find out the numbers of ways to generate a number using K Fibonacci numbers only.
Constraints:
1<=K<=10
1<=N<=10^9
For Example:
N=14 and K=3
There are two ways:
(8,5,1) and (8,3,3)
Here is my recursive solution:
public static void num_gen(int i ,long val ,int used){
if(used==0){
if(val==n) ans++;
return ;
}
if(i==Fib.length) return ;
for(int j=0;j<=used;j++){
long x = j*Fib[i];
if(x+val<=n){
num_gen(i+1,x+val, used-j);
}
}
}
This solution will timeout for large value of N and K=10. Can you provide me algorithm with better complexity.
This can be expressed as multiplying polynomials where exponents are Fibonacci numbers.
Number of factors is K.
The result is a coefficient of the member of the result polynomial whose exponent equals N.
Example:
What is the number of ways to compose number 7 from 3 numbers where each of these 3 numbers can be 1,2 or 3.
(x + x² + x³)³ = x⁹ + 3x⁸ +6x⁷ + 7x⁶ + 6x⁵ + 3x⁴ + x³
Result is 6 since it is the coefficient of the x⁷ member of the result polynomial.
I'd like to give you a solution that works in another language, and I hope that helps you learn in the process of translating it to Java. Because I'm unclear on how to otherwise help you fix the recursive solution you're working on, as I believe that no recursion is required. Also no preset array of Fibonacci numbers is needed.
This is in Perl, it worked for:
$ perl fibber.pl 3 14
8,5,1
8,3,3
2 matches
But I can't guarantee it's perfectly right.
#!/usr/bin/perl
use bigint;
use List::Util qw(sum);
my ($digits, $goal) = #ARGV;
if (!($digits > 0) || !($goal > 0)) {
die "Missing 2 arguments: the number count to sum, the value they sum to.";
}
sub fib {
my ($a, $b) = #_;
return sub {
if (0 == scalar #_) {
(my $r, $a, $b) = ($a, $b, $a+$b);
return $r;
} else {
($a, $b) = #_;
(my $r, $a, $b) = ($b, $a+$b, $a+$b+$b);
return $r;
}
}
}
my #f = (0) x $digits;
#f = map {fib(1,2)} #f;
my #d = map {$_->()} #f;
my $count = 0;
while ($d[0] < $goal) {
if ($goal == sum #d) {
$count++;
print(join(",", #d)."\n");
}
my ($i, $a, $b) = (0, $d[$i], $f[$i]->());
$d[$i] = $b;
while ($goal <= $d[$i]) {
$i++;
if ($i == $digits) {
print "$count matches\n";
exit 0;
}
($a, $b) = ($d[$i], $f[$i]->());
$d[$i] = $b;
}
while ($i > 0) {
$i--;
$d[$i] = $f[$i]->($a, $b);
}
}
I am trying to solve this question as the preparation for a programming interview:
A frog only moves forward, but it can move in steps 1 inch long or in jumps 2 inches long. A frog can cover the same distance using different combinations of steps and jumps.
Write a function that calculates the number of different combinations a frog can use to cover a given distance.
For example, a distance of 3 inches can be covered in three ways: step-step-step, step-jump, and jump-step.
I think there is a quite simple solution to this, but I just can't seem to find it. I would like to use recursion, but I can't see how. Here is what I have so far:
public class Frog {
static int combinations = 0;
static int step = 1;
static int jump = 2;
static int[] arr = {step, jump};
public static int numberOfWays(int n) {
for (int i = 0; i < arr.length; i++) {
int sum = 0;
sum += arr[i];
System.out.println("SUM outer loop: " + sum + " : " + arr[i]);
while (sum != 3) {
for (int j = 0; j < arr.length; j++) {
if (sum + arr[j] <= 3) {
sum += arr[j];
System.out.println("SUM inner loop: " + sum + " : " + arr[j]);
if (sum == 3) {
combinations++;
System.out.println("Combinations " + combinations);
}
}
}
}
}
return combinations;
}
public static void main(String[] args) {
System.out.println(numberOfWays(3));
}
}
It doesn't find all combinations, and I think the code is quite bad. Anyone have a good solution to this question?
Think you have an oracle that knows how to solve the problem for "smaller problems", you just need to feed it with smaller problems. This is the recursive method.
In your case, you solve foo(n), by splitting the possible moves the frog can do in the last step, and summing them):
foo(n) = foo(n-1) + foo(n-2)
^ ^
1 step 2 steps
In addition, you need a stop clause of foo(0) = 1, foo(1)=1 (one way to move 0 or 1 inches).
Is this recursive formula looks familiar? Can you solve it better than the naive recursive solution?
Spoiler:
Fibonacci Sequence
Here's a simple pseudo-code implementation that should work:
var results = []
function plan(previous, n){
if (n==0) {
results.push(previous)
} else if (n > 0){
plan(previous + ' step', n-1)
plan(previous + ' hop', n-2)
}
}
plan('', 5)
If you want to improve the efficiency of an algorithm like this you could look into using memoization
Here's a combinatoric way: think of n as 1 + 1 + 1 ... = n. Now bunch the 1's in pairs, gradually increasing the number of bunched 1's, summing the possibilities to arrange them.
For example, consider 5 as 1 1 1 1 1:
one bunch => (1) (1) (1) (11) => 4 choose 1 possibilities to arrange one 2 with three 1's
two bunches => (1) (11) (11) => 3 choose 2 possibilities to arrange two 2's with one 1
etc.
This seems directly related to Wikipedia's description of Fibonacci numbers' "Use in Mathematics," for example, in counting "the number of compositions of 1s and 2s that sum to a given total n" (http://en.wikipedia.org/wiki/Fibonacci_number).
This logic is working fine. (Recursion)
public static int numberOfWays(int n) {
if (n== 1) {
return 1; // step
} else if (n== 2) {
return 2; // (step + step) or jump
} else {
return numberOfWays(n- 1)
+ numberOfWays(n- 2);
}
}
The accepted answer fails performance test for larger sets. Here is a version with for loop that satisfies performance tests at testdome.
using System;
public class Frog
{
public static int NumberOfWays (int n)
{
int first = 0, second = 1;
for ( int i = 0; i<n; i++ )
{
int at = first;
first = second;
second = at + second;
}
return second;
}
public static void Main (String[] args)
{
Console.WriteLine (NumberOfWays (3));
}
}
C++ code works fine.
static int numberOfWays(int n)
{
if (n == 1) return 1;
else if (n == 2) return 2;
else
{
static std::unordered_map<int,int> m;
auto i = m.find(n);
if (i != m.end())
return i->second;
int x = numberOfWays(n - 1) + numberOfWays(n - 2);
m[n] = x;
return x;
}
}
public static int multiply2(int num1, int num2) {
if (num1 == 0 || num2 == 0) {
return 0;
}
else {
return num1 + multiply2(num1, num2 - 1);
}
}
I just realized that it would be fun to make a program that could determine the product of two numbers, one or both being negative. I want to do it using recursive multiplication (basically repeated addition). Could some one help me out? Thanks!
if (num1 == 0 || num2 == 0) {
return 0;
}
else if( num2 < 0 ) {
return - num1 + multiply2(num1, num2 + 1);
}
else {
return num1 + multiply2(num1, num2 - 1);
}
You would test if it's negative and subtract instead of add:
public static int multiply2(int num1, int num2) {
if (num1 == 0 || num2 == 0) {
return 0;
}
else if(num2 > 0){
return num1 + multiply2(num1, num2 - 1);
}
else{
return -num1 + multiply2(num1, num2 + 1);
}
}
else if (num1 < 0 || num2 < 0) {
int signum1 = num1 < 0 ? -1 : 1;
int signum2 = num2 < 0 ? -1 : 1;
return signum1 * signum2 * multiply(signum1 * num1, signum2 * num2);
} else {
Something like that
Note: there is a signum function and Math.abs can be used for signum * num
You will need to add if number is -ve. If you see we are adding only first number and for second number condition we have to reach is 0. So if negative do+1 if positive do -1
else if (num2 < 0)
return -num1 + multiply2(num1, num2 + 1);
else
return num1 + multiply2(num1, num2 - 1);
System.out.println(multiply2(5, -6));-->-30
System.out.println(multiply2(5, 6));-->30
Instead of dealing with it multiple times in the main recursion part, a better idea would be to handle it as an edge case and just convert it into a regular case since both the assignment and return will not occur until the mathematical operation has finished.
To do this, I converted y into a positive number and then negated the result of the function as a whole once the result has returned to the negative case.
Here's my solution:
private static int product(int x, int y) {
// Negative start edge case
if (y < 0) {
return -1 * product(x, y * -1);
}
// Edge case (only for speed)
if (y == 0 || x == 0) {return 0;}
// Base case
if (y == 1) {
return x;
}
// Recursion
return x + product(x, y-1);
}
It's worth noting that even with out the 0 edge case, the method would still work. In this case the method would just need to make a few more than necessary to get the result.
Testing has concluded that this method works with either parameter being 0 and/or negative.
public static int multiply2(int num1, int num2) {
if (num1 == 0 || num2 == 0) {
return 0;
}
else {
int sign2=(int)(Math.abs(num2)/num2);
return sign2*num1 + multiply2(num1,num2-sign2);
}
}
David Wallace's answer is good but if the input is (1,124) or (-1,124) the depth of recursion (number of times the method calls itself) will be 123, not very efficient. I would suggest adding a couple of lines to test for 1 or -1. Here's a full example:
public class Multiply {
public static void main(String[] args) {
System.out.print("product = " + multiply(1, 124) );
}
public static int multiply(int x, int y) {
System.out.println("Multiply called: x = " + x + ", y = " + y);
if (x == 0 || y == 0) {
System.out.println("Zero case: x = " + x + ", y = " + y);
return 0;
}
else if (x == 1 && y > 0) {
return y;
}
else if (y == 1 && x > 0) {
return x;
}
else if ( x == -1 && y > 0) {
return -y;
}
else if ( y == -1 && x > 0) {
return -x;
}
else if( y == -1 ) {
System.out.println("y is == -1");
return -x;
}
else if( x == -1 ) {
System.out.println("x is == -1");
return -y;
}
else if( y < 0 ) {
System.out.println("y is < 0");
return -x + multiply(x, y + 1);
}
else {
System.out.println("Last case: x = " + x + ", y = " + y);
return x + multiply(x, y - 1);
}
}
}
Output:
Multiply called: x = 1, y = 124
product = 124
Okay, so I am actually working on this one for homework. Recursive solutions implement - or use - a base case against which the need to continue is determined. Now, you might say, "What on Earth does that mean?" Well, in laymen's terms, it means we can simplify our code (and, in the real world, save our software some overhead) - about which I will explain, later. Now, a part of the issue is understanding some basic math, namely, a negative plus a negative is a negative or minus a positive ( -1 + -1 = -2) depending upon the math teacher to whom you speak (we'll see that come into play in the code, below).
Now, there is some debate to be had, here. About which I will write, later.
Here is my code:
public static int multiply(int a, int b)
{
if (a == 0)
{
return result;
}
else if (a < 0) // Here, we only test to see whether the first param.
// is a negative
{
return -b + multiply(a + 1, b); // Here, remember, neg. + neg. is a neg.
} // so we force b to be negative.
else
{
result = result + b;
return multiply(Math.abs(a - 1), b);
}
}
Notice there are a two things done differently, here:
The code above does not test the second parameter to see whether the second parameter is negative (a < 0) because of the mathematical principle in the first paragraph (see bold text in first paragraph). Essentially, if I know I am multiplying (y) by a negative number (-n), I know I am taking -n and adding it together y number of times; therefore, if the multiplicand or multiplier is negative, I know I can take either of the numbers, make the number negative, and add the number to itself over and over again, e.g. -3 * 7 could be written (-3) + (-3) + (-3) + (-3)... etc. OR (-7) + (-7) + (-7)
NOW HERE IS WHAT'S UP FOR DEBATE: That above code does not test to see whether the second number (int b) is 0, i.e. multiplying by 0. Why? Well, that's personal choice (sort of). The debate here must weigh the relative significance of something: the overhead for each choice (of either running an equals-zero test or not). If we do test to see if one side is zero, each time the recursive call to multiply is made, the code must evaluate the expression; however, if we do not test for equals zero, then the code adds a bunch of zeros together n number of times. In reality, both methods "weigh" the same - so, to save memory, I leave out the code.