I have three integers, which are assigned to variables after being passed in as command line parameters. I want to validate that each of the integers are in the range 1-5. Is there a way to accomplish this in Java without using an if statement like the one below? I'd like to avoid doing this (note- pseudocode):
if ((a & b & c) > 0 && (a & b & c) < 6) {
//blah blah
}
Mainly, this wouldn't scale well if additional parameters were added in the future, etc. Is there a more elegant way to accomplish this?
The only improvement I think could be made (for readability) is this:
public boolean isInRange(int i) {
return i > 0 && i < 6;
}
Then call that function instead.
If a, b, and c are related, you may also consider using an array and looping through that. Something like:
public boolean allInRange(int[] arr) {
for (int i = 0; i < arr.length; i ++) {
if (!isInRange(arr[i])) return false;
}
return true;
}
How about something like this:
validate(int ... args) {
for (int arg : args) {
if (arg < 1 || arg > 5) {
throw IllegalArgumentException("Argument is not in valid range [1..5]: " + arg);
}
}
}
and then call this helper method
validate(a,b,c);
You could create a method to which you pass an integer, and the method can return a boolean depending whether or not it is in range.
Another way is to create a method that receives a list of integers List<Integer> myList or an array of integers, and checks each and every one if it is in range.
Here is a faster way to do that without using multiple &&s (for integers only):
private static boolean isInRange(int num, int min, int max) {
return (num - min - Integer.MIN_VALUE) <= (max - (1 - Integer.MIN_VALUE));
}
Usage:
public static void main(String[] args) {
System.out.println(isInRange(5,1,7)); // true
System.out.println(isInRange(5,1,3)); // false
}
Related
Trying to sort the array based on the number of factors using a custom comparator function, but the output remains same as input.
Sorting isnt working
public void solve(){
Integer[] A = new Integer[]{3,9,4,6,12,10,7};
System.out.println(Arrays.toString(A));
Arrays.sort(A, (A1, B) -> {
int fact_a = calcFactors(A1);
int fact_b = calcFactors(B);
if(fact_a < fact_b) return 1;
if(fact_a==fact_b){
if(A1 < B) return 1;
}
return 0;
});
System.out.println(Arrays.toString(A));
}
public int calcFactors(int A){
int count = 0;
int sqrt = (int)Math.sqrt(A);
for(int i =1;i<=sqrt;i++){
if(A%i == 0) count+=2;
}
if(sqrt*sqrt == A) count--;
return count;
}
It looks like your comparator only checks for the case that a < b. Properly implemented comparators need to return not only 1 when a > b, but also 0 when a == b and -1 when a < b.
You could expand your if logic to cover those cases, but fortunately, there's an easier way - Integer.compare():
int result = Integer.compare(fact_a, fact_b);
if (result == 0) {
result = Integer.compare(A1, B);
}
return result;
Integer.compare() handles most of the logic for you; the only thing you need to do is check if the result of the factor comparison is 'equal', and if so, apply the fallback comparison of the numbers themselves
(note: for the sake of this answer I'm assuming that calcFactors is implemented properly...)
Your comparator should return -1 if A1 is intended to come before B in the sort order, or 1 if A1 is intended to come after B. Returning 0 should only happen if A1 and B are equal in terms of the sorting. But you have returned 0 in a lot of cases where A1 is intended to come after B.
I think you intended your logic to be something like this.
if(fact_a < fact_b){
return -1;
}
else if(fact_a == fact_b){
if(A1 < B) {
return -1;
}
else if(A1 == B) {
return 0;
}
else {
return 1;
}
}
else {
return 1;
}
A simpler way of writing this is found in Kevin K's answer, which I have just upvoted. But this shows you, longhand, what the logic needs to be.
I'm having some problems whit an exercise I found.
I was provided a method, and can't make any changes to it.
Inside said method, I should identify the first repeating digit, beetwen two integers, And return it's position.
For example: 1234 and 4231 results in 1.
And I managed to make it work,
It's just that it doesn't work if I try to use the method more than once, it simply keeps adding to the previous value.
This is my code so far
public static final int BASENUMERACAO = 10;
public static int indice = 0;
private static int getLowestIndexWithSameDigit(int a, int b) {
if (a < 0 || b < 0) {
throw new IllegalArgumentException("Both numbers should positive " + a + " " + b);
} else {
if (a % BASENUMERACAO == b % BASENUMERACAO) {
return indice;
} else if (a / BASENUMERACAO != 0 && b / BASENUMERACAO != 0) {
indice++;
return getLowestIndexWithSameDigit(a / BASENUMERACAO, b / BASENUMERACAO);
} else {
return -1;
}
}
I tried passing index, as a local variavel, but it just overrides the curent value, everytime it's called, therefore only returning 0 or -1
Could someone tell me how to I do keep count in a recursive method, or just how do I identify the digit whitout a counter?
The problem is that you are retaining state from the previous invocation, in the indice variable. indice is an example of mutable global state, which is generally a bad idea for the reason you are experiencing here: you might carry over the results of previous calculations into new calculations, leading to unpredictable (or maybe unexpected) results.
Make your indice variable a parameter of the method:
private static int getLowestIndexWithSameDigit(int a, int b, int indice) {
// ...
}
So your recursive call will also pass a value for this:
return getLowestIndexWithSameDigit(a / BASENUMERACAO, b / BASENUMERACAO, indice);
To start the iteration, you can either explicitly pass 0, or you can create a method which takes just a and b:
private static int getLowestIndexWithSameDigit(int a, int b) {
return getLowestIndexWithSameDigit(a, b, 0);
}
Create another method to call your recursive method and use the vars that you need as parameter for the recursive version and keep passing them.
Something like:
private static int myMethod( int a, int b ) {
return myRecursiveMethod( a, b, 0, 0 );
}
private static int myRecursiveMethod( int a, int b, int var1, int var2 ) {
// do the recursive work...
myRecursiveMethod( newValueForA, newValueForB, var1, var2 ) {
}
I was writing a recursive algorithm to calculate Fibonacci numbers in Java as part of a programming 101 course. This is the code:
public class Fib {
public static void main(String[] args) {
Fib fib = new Fib();
}
public Fib() {
int end = 9;
long[] nums = new long[2];
printFib(0, end, nums);
}
private void printFib(int i, int end, long[] nums) {
while(i < end) {
if(i == 0 || i == 1) {
nums[i] = 1;
System.out.println("1");
} else {
long fib;
fib = 0;
fib += (nums[0] + nums[1]);
nums[0] = nums[1];
nums[1] = fib;
System.out.println(fib);
}
i++;
printFib(i, end, nums);
}
}
}
As I was stepping through the program it was working as intended until i became equal to end, the variable telling the printFib method how many Fibonacci numbers it should print out. When ì was equal to end while(i < 1) returns false as expected and the program go to the last }, now you'd(me)
expect the program to return the constructor from which I initially called the function and the program should exit, this not the case. The program goes back to the while statement and somehow evaluates to false again. Then it does the same thing again except the second time it decreases i by 1(what?!) and then proceeds to the else clause when it reaches the if statement. It then does the same thing over and over alternating the amount it subtracts from i between 1 and 2. I've asked my teacher about this and he was unable to explain it.
The program works fully like I intended if I replace the while with an if so maybe there is something about while that I don't know.
Edit
So I realize now that each time the method is called i has a different value which is stored and when the method exits and i = end the program goes back to the previous calls where i had a different value.
You implemented an iterative algorithm to calculate Fibonacci series. That's what the while loop does. There is no point in making the recursive call - printFib(i, end, nums) - at the end.
If you intended a recursive implementation, the entire while loop is not needed.
This code doesn't look right to me.
I would recommend that you not print from your method. Return a value to the main and let it print.
Your recursive method should not have a while loop in it. That's iteration - exactly what you're trying to avoid here.
Your method should have a stopping condition and a call to itself. That's not what you're doing.
Think about it like this:
/**
* Recursive Fibonnaci
* User: mduffy
* Date: 2/11/2015
* Time: 8:50 AM
* #link http://stackoverflow.com/questions/28455798/strange-behavior-in-recursive-algorithm/28455863#28455863
*/
public class Math {
private static Map<Integer, Integer> memo = new ConcurrentHashMap<Integer, Integer>();
public static void main(String [] args) {
for (String arg : args) {
int n = Integer.valueOf(arg);
System.out.println(String.format("n: %d fib(n): %d", n, fibonnaci(n)));
}
}
public static int fibonnaci(int n) {
if (n < 0) throw new IllegalArgumentException("index cannot be negative");
int value = 0;
if (memo.containsKey(n)) {
value = memo.get(n);
} else {
if (n <= 1) {
value = n;
} else {
value = fibonnaci(n-1)+fibonnaci(n-2);
}
memo.put(n, value);
}
return value;
}
}
Basicly this is happening because i would guess that you are thinking of i as an reference which will influence the basic callings of the Fibunacci method calling the sub Fibunacci method. This will finally lead way to many calls of the fibunacci method.
in my eyes the loop doesn´t make sense in your recursive way of solving it.
I'm thinking of several elegant ways of writing a simple Lisp-like recursive function in Java that does, let's say, a simple summation.
In Common Lisp it would be like this:
(defun summation(l)
(if l
(+ (car l) (summation (cdr l)))
0))
(summation '(1 2 3 4 5)) ==> 15
In Java the one of many possible solutions would be:
public int summation(int[] array, int n) {
return (n == 0)
? array[0]
: array[n] + summation(array, n - 1);
}
CALL:
summation(new int[]{1,2,3,4,5}, 4); //15
1) Is there any possible way NOT to use the index n?
2) Or leave your solution (non-iterational) which you see as interesting.
Thanks.
Using Java Collections - something like this should give you an idea of how to eliminate n and recurse in terms of the list size instead:
public int summation( List<Integer> list ) {
return list.isEmpty()
? 0
: list.get( list.size - 1 ) + summation( list.subList( 0 , list.size() - 1 ) );
}
Cheers,
Usually, I solve this kind of recursion with a public API that does not require the index parameter and a private API with any signature I#d like it to be. For this I would separate it this way:
public int summation(int[] numbers) {
return summation(numbers, numbers.length - 1);
}
private int summation(int[] numbers, int till) {
return (till < 0) ? 0 : numbers[till] + summation(numbers, till - 1);
}
Note that you must check till < 0 as this handles an empty array correctly.
Another way would be to not use an array, but any Iterable<Integer>:
public int summation(Iterable<Integer> numbers) {
return summation(numbers.iterator());
}
private int summation(Iterator<Integer> numbers) {
return (numbers.hasNext()) ? numbers.next() + summation(numbers) : 0;
}
Hint: The order of calls in numbers.next() + summation(numbers) is important, as the next() call must be done first.
If you use List.subList method, it may perform iteration, underneath. You can use Queue instead, to avoid iteration. For example:
public int sum(Queue queue) {
return queue.isEmpty() ? 0 : (queue.poll() + sum(queue));
}
public class HelloWorld{
static int sum=0;
static int c;
public static void main(String []args){
int[] y={1,2,3,4,5};
c=y.length;
System.out.println( summation(y)); //15
}
public static int summation(int[] array) {
c--;
if(c<0){
return sum;
}
else{
sum+=array[c];
return summation(array);
}
}
}
Here's a simple method that seems pretty close to what's being asked for.Basically, we are taking a recursive approach to performing summation ascontrasted with brute force from the bottom up.
public static int sumToN(int n) {
if( n == 0 ){
return 0;
}
return n + sumToN(n - 1);
}
I am having a lot of trouble with this basic recursion problem in java; any pointers would be great.
"Write a static recursive method to print out the nth term of the
geometric sequence: 2, 6, 18, 54."
From what I can gather, somewhere in the code I should be recursively multiplying something by 3, but I'm struggling to figure out how to do this. I know I need a termination statement, but when does that occur? Do I need a helper method?
A Recursive Function is a function whose implementation references itself. Below is some funny example:
public class Inception {
public void dream() {
boolean enoughDreaming = false;
//Some code logic below to check if it's high time to stop dreaming recursively
...
...
if(!enoughDreaming) {
dream(); //Dream inside a Dream
}
}
}
And the solution for your problem:
public class GeometricSequence {
public static void main(String[] args) {
//Below method parameters - 5 = n, 1 = count (counter), res = result (Nth number in the GP.
System.out.println(findNthNumber(5, 1, 2));
}
public static int findNthNumber(int n, int count, int res) {
return ((count == n)) ? res : findNthNumber(n, count+1, res *3);
}
}
EDIT:
The above class uses "int", which is good only for small numbers (because of Integer Overflow problem). The below class is better for all types/numbers:
public class GeometricSequence {
public static void main(String[] args) {
//Below method parameters - 5 = n, 1 = count (counter), res = result (Nth number in the GP.
System.out.println(findNthNumber(2000, 1, new BigInteger("2")));
}
public static BigInteger findNthNumber(int n, int count, BigInteger res) {
return ((count == n)) ? res : findNthNumber(n, count+1, res.multiply(new BigInteger("3")));
}
}
This is the simplest example of recursion.
You need a method declaration.
You need to check if the end has been reached.
Otherwise you need to call the method again with an operation which makes the difference between one term and the next.
Yes, you need a termination condition - basically when you've taken as many steps as you need. So consider how you want to transition from one call to another:
How are you going to propagate the results so far?
What extra state do you need to keep track of how many more steps you need to take?
What are you going to return from the method?
Here's a C# example (I know your doing Java but it's pretty similar)
public static void Recursive(int counter, int iterations, int value, int multiplier)
{
if (counter < iterations)
{
Console.WriteLine(value);
counter++;
Recursive(counter, iterations, (value * multiplier), multiplier);
}
}
So when you run the function you enter the parameters
"counter" will always be 0 when you first call it
"iterations" is the value of n
"value" is your starting value, in your case 2
"multiplier" is how much you want to multiply by each iteration, in your case 3
Every time it runs it will check to see if counter is less than iterations. If it is more, the value is printed, the counter is incremented, the value is multiplied by the multiplier and you add the same parameters back in to the function.
A recursive solution: Seq(1) is the first element of the sequence .... Seq(n-th)
public static void main(String args[]) throws Exception {
int x = Seq(3); //x-> 18
}
public static int Seq(int n){
return SeqRec(n);
}
private static int SeqRec(int n){
if(n == 1)
return 2;
else return SeqRec(n - 1) * 3;
}
Non-Recursive solution:
public static int Non_RecSeq(int n){
int res = 2;
for(int i = 1; i < n; i ++)
res *= 3;
return res;
}
public static void main(String args[]) throws Exception {
int x = Non_RecSeq(3); //x-> 18
}