I have to write a method which returns true if three 3s are present in an integer array(provided they are not consecutive).
I have written this code here: However, it is returning true (which it should not do). Can someone point out my mistake?
arr[]={{4,3,5,2,3,3};
Also, this is a linear algorithm. Can it be done better?
public static boolean consecutiveThree(int[] arr) {
int x=0;
for(int i=0;i<arr.length-1;i++) {
if((arr[i]!=3 && arr[i+1]==3) || (arr[i]==3 && arr[i+1]!=3)) {
x++;
//continue;
}
if(x==3)
return true;
}
return false;
}
You said:
returns true if three 3s are present in an integer array(provided they are not consecutive)
I interpret that as having at least three 3s, and no two 3s are adjacent.
public static boolean hasThreeNonconsecutiveThrees(int... values) {
int count = 0, streak = 0;
for (int value : values) {
if (value != 3)
streak = 0;
else if (++streak == 2)
return false; // Found two consecutive (adjacent) 3s
else
count++;
}
return (count >= 3);
}
Test
System.out.println(hasThreeNonconsecutiveThrees(4,3,5,2,3,3)); // false
System.out.println(hasThreeNonconsecutiveThrees(4,3,5,3,2,3)); // true
System.out.println(hasThreeNonconsecutiveThrees(1,2,3,4,3)); // false
System.out.println(hasThreeNonconsecutiveThrees(4,3,5,3,3,3)); // false
Output
false
true
false
false
At worst case the correct array will end with ... 3 3 X 3. Unless the array is somewhat sorted or somewhat special you will have to look at every single element to reach the last three 3s. If the array is random, you need linear complexity since you have to review every single element in the array.
Your algorithm is not checking the whether arr[i-1] is '3'. That is your algorithm's mistake.
Try this:-
public static boolean consecutiveThree(int[] arr) {
int x = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 3) {
if (i == 0) { // zero 'th element do not have arr[i-1].
if(arr[i + 1] != 3) {
x++;
}
} else if (i == arr.length - 1) { // last element do not have arr[i+1].
if((arr[i - 1] != 3)) {
x++;
}
} else if ((arr[i + 1] != 3) && (arr[i - 1] != 3)) {
x++;
}
}
if (x == 3) // may be x >= 3
return true;
}
return false;
}
Related
The task is to implement a program which counts how many different Sums of Primes there are for a given number sumtoBreak.
The Method primeSum should subtract all possible primes currprime from the number sumtoBreak until the sumtoBreak becomes zero and then return (in sum) a one for each possibilty. To account for all possibilities, in each recession step, it calls itself
with sumtoBreak - currprime plus
calls itself with the nextPrime.
My Problem is that java won't return anything unless the sumtoBreak is zero right at the beginning.
Would be glad for any advice!
Here's the code (I know that the parenthesis in the code with the nested if statements are redundant, but I just wanted to make sure, that's not the problem):
Here's the fixed code:
public class PrimeSum {
public static boolean isPrime(int primecandidate) {
int count = 0;
for (int i = 2; i <= primecandidate / 2; i++) {
if (primecandidate % i == 0)
count++;
}
if (count == 0)
return true;
else
return false;
}
public static int nextPrime(int currprime) {
int j = currprime + 1;
while (!isPrime(j))
j++;
return j;
}
public static int primeSum(int sumtoBreak, int currprime) {
if (sumtoBreak == 0) {
return 1;
} else {
if (sumtoBreak < 0 || currprime > sumtoBreak) {
return 0;
} else {
return primeSum(sumtoBreak, nextPrime(currprime)) + primeSum(sumtoBreak - currprime, currprime);
}
}
}
public static void main(String[] args) {
System.out.println(primeSum(Integer.parseInt(args[0]), 2));
}
}
This doesn't answer your question, but corrects an error in your isPrime Method and computes the result much faster:
private static boolean isPrime(final int primecandidate) {
if ( primecandidate < 2) { // 0 & 1 are NOT Prime
return false;
}
if ((primecandidate & 0x1) == 0) { // Even is NOT Prime...
return primecandidate == 2; // ...except for 2 (and 0).
}
for (int i = 2, iMax = (int) Math.sqrt(primecandidate); i <= iMax; i++) {
if (primecandidate % i == 0) {
return false;
}
}
return true;
}
Note the following:
the final argument primecandidate is marked final
it corrects the result for 0 & 1 to false
the method is marked private
the iMax is Sqrt(primecandidate) & not primecandidate / 2
iMax is calculated once, instead of every iteration
I use a strategy I call "if you're done, be done."
Meaning: don't set a flag (in your case count), just get out!
Please note also, there is an apache commons Math3 function...
org.apache.commons.math3.primes.Primes.isPrime(j)
It is significantly slower for smallish values (<= Short.MAX_VALUE)
It is somewhat faster for largeish values (ca. Integer.MAX_VALUE)
There is also a BigInteger.isProbablePrime(...) function, but my Benchmark suggests it is rather slow.
I hope this helps a little?
Some things you might have missed:
in a function, a return statement terminates (break) the function immediatly. So in
if(...) { return ...; }
else {...}
→ else is redundant, as if the condition is true, the function is already terminated (break)
Something like a==0 has a boolean value (true or false). So
if(count==0) { return false; }
else { return true;}
can be shortened to return count!=0;
I recommend to always use braces, because something like if(i==0) ++i; break;, means if(i==0) {++i;}. break; will be called in any case.
public static boolean
isPrime(int n)
{
if(n==0 || n==1) { return false; }
for(int i= 2; i <= n/2; ++i)
{
if(n%i == 0) { return false; } //we know, n is not a prime,
//so function can break here
}
return true; //since for all values of i, the function did not break,
//n is a prime
}
I wish you a lot of motivation to code for the future!
I want to increment (+1) the last digit of an int array that has N values and represents a whole number. Each value is a single digit between 0-9.
The logic is like this: if the digit that has to be incremented is 9, it has to become 0 and the next one (from right to left) has to be incremented by 1. If you reach the first digit of the array and it is a 9, this will become a 10. Examples:
[3,4,5,6] -> [3,4,5,7]
[3,9,2,9] -> [3,9,3,0]
[3,4,9,9] -> [3,5,0,0]
[9,9,9,9] -> [10,0,0,0]
I had the same exercise but with only 4 digits, so the logic was simple:
int[] incrementArrayDigits(int[] fourDigits) {
if (fourDigits[3] != 9) {
fourDigits[3]++;
} else if (fourDigits[2] != 9) {
fourDigits[3] = 0;
fourDigits[2]++;
} else if (fourDigits[1] != 9) {
fourDigits[3] = 0;
fourDigits[2] = 0;
fourDigits[1]++;
} else if (fourDigits[0] != 9) {
fourDigits[3] = 0;
fourDigits[2] = 0;
fourDigits[1] = 0;
fourDigits[0]++;
}
if (fourDigits[0] == 9 && fourDigits[1] == 9 && fourDigits[2] == 9 &&
fourDigits[3] == 9) {
fourDigits[1] = fourDigits[2] = fourDigits[3] = 0;
fourDigits[0] = 10;
}
System.out.println(Arrays.toString(fourDigits));
return fourDigits;
}
I tried to solve the problem for N numbers taking the length of the array and then using a for loop but I cannot reach the expected result.
One way to solve this is to use recursion.
The idea is to keep track of which element of the array you are incrementing. You start with the element at index array.length - 1, increment it, if it reaches 10, set it to 0, then do the same thing to the element at index array.length - 2, and so on.
Also note that since you are changing the array in the method, you don't have to return the array.
private static void incrementArrayDigits(int[] array, int position) {
if (position >= array.length || position < 0) {
return;
}
array[position]++;
if (array[position] == 10 && position != 0) {
array[position] = 0;
incrementArrayDigits(array, position - 1);
}
}
// usage:
int[] array = {9,9,9};
incrementArrayDigits(array, array.length - 1);
System.out.println(Arrays.toString(array));
In fact, what you really want to achieve is the "PLUS 1". If your N <= 10, use int directly. if your N <=10, use long.
Of course, if you N really need very large. Try implement a class for the digit?
One possible solution is to iterate backwards over your array and increment if needed:
private static int[] incrementArrayDigits(int[] fourDigits) {
for (int i = fourDigits.length - 1; i >= 0; i--) {
fourDigits[i]++; // increment
if (i > 0) { // cut result to 0-9, if not the first value
fourDigits[i] %= 10;
}
if (fourDigits[i] > 0) { // if no carry is passed break
break;
}
}
return fourDigits;
}
This is a solution I came up with. Hope it helps!
public void incrementArrayDigits(int[] arr) {
if(arr == null)
return;
int currIndex = arr.length - 1;
while(currIndex > -1){
arr[currIndex]++;
if(arr[currIndex] < 10)
return;
else if (currIndex < 1)
return;
else
arr[currIndex--] = 0;
}
}
This is the question : An array is sorted (in ascending order) if each element of the array is less than or equal to the next element.
Write a boolean-valued method named isSorted that accepts an integer array, and the number of elements in the array and returns whether the array is sorted.
Before showing the code : my logic is that an if else-if and else statement should first determine if the size of the array is 0,1,or 2. This is because when the size equals 1 or 2, the program must break. When the size is larger than 2, the program should check arr[size-1] > arr[size-2] and then call the method again with size decremented if that is true and just return false if it is untrue. When I ran that program, the following 2 tests failed : [1,3,2,4] and [2,1,2,3,4]. Because of this I specified that when the size is equal to 2, the method returns false if arr[0] > arr[1] however it didn't work. What am I doing wrong? I don't want to just look up the answer because I am studying for a test so I am sorry if there are repeated answers.
I know the loop is better I just wanted to study recursion
public boolean isSorted(int[] arr, int size) {
if(size == 0 || size == 1) {
return true;
} else if (size == 2) { //this is the part I don't get.
if (arr[0] > arr[1]) {
return false;
} else {
isSorted(arr,size-1);
return true;
}
} else {
if (arr[size-1] < arr[size-2]) {
return false;
} else {
isSorted(arr, size-1);
return true;
}
}
}
Recursion is not good way to solve this problem. What if your array will be very big and you could get StackOverflowError. Why not to use simple if operator:
public static boolean isSorted(int[] arr, int size) {
if (arr.length >= 2)
for (int i = 1; i < arr.length; i++)
if (arr[i - 1] > arr[i])
return false;
return true;
}
You need return the result from isSorted, for example, change:
isSorted(arr, size-1);
return true;
to
return isSorted(arr, size-1);
And, the case else if (size == 2) is redundant. size 2 should have the same logic with size 3, 4, 5, ...
Complete code:
public boolean isSorted(int[] arr, int size) {
if (size == 0 || size == 1) {
return true;
} else {
if (arr[size - 1] < arr[size - 2]) {
return false;
} else {
return isSorted(arr, size - 1);
}
}
}
I am practicing past exam papers for a basic java exam, and I am finding it difficult to make a for loop work for testing whether a number is prime. I don't want to complicate it by adding efficiency measures for larger numbers, just something that would at least work for 2 digit numbers.
At the moment it always returns false even if n IS a prime number.
I think my problem is that I am getting something wrong with the for loop itself and where to put the "return true;" and "return false;"... I'm sure it's a really basic mistake I'm making...
public boolean isPrime(int n) {
int i;
for (i = 2; i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
The reason I couldn't find help elsewhere on stackoverflow is because similar questions were asking for a more complicated implementation to have a more efficient way of doing it.
Your for loop has a little problem. It should be: -
for (i = 2; i < n; i++) // replace `i <= n` with `i < n`
Of course you don't want to check the remainder when n is divided by n. It will always give you 1.
In fact, you can even reduce the number of iterations by changing the condition to: - i <= n / 2. Since n can't be divided by a number greater than n / 2, except when we consider n, which we don't have to consider at all.
So, you can change your for loop to: -
for (i = 2; i <= n / 2; i++)
You can stop much earlier and skip through the loop faster with:
public boolean isPrime(long n) {
// fast even test.
if(n > 2 && (n & 1) == 0)
return false;
// only odd factors need to be tested up to n^0.5
for(int i = 3; i * i <= n; i += 2)
if (n % i == 0)
return false;
return true;
}
Error is i<=n
for (i = 2; i<n; i++){
You should write i < n, because the last iteration step will give you true.
public class PrimeNumberCheck {
private static int maxNumberToCheck = 100;
public PrimeNumberCheck() {
}
public static void main(String[] args) {
PrimeNumberCheck primeNumberCheck = new PrimeNumberCheck();
for(int ii=0;ii < maxNumberToCheck; ii++) {
boolean isPrimeNumber = primeNumberCheck.isPrime(ii);
System.out.println(ii + " is " + (isPrimeNumber == true ? "prime." : "not prime."));
}
}
private boolean isPrime(int numberToCheck) {
boolean isPrime = true;
if(numberToCheck < 2) {
isPrime = false;
}
for(int ii=2;ii<numberToCheck;ii++) {
if(numberToCheck%ii == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
}
With this code number divisible by 3 will be skipped the for loop code initialization.
For loop iteration will also skip multiples of 3.
private static boolean isPrime(int n) {
if ((n > 2 && (n & 1) == 0) // check is it even
|| n <= 1 //check for -ve
|| (n > 3 && (n % 3 == 0))) { //check for 3 divisiable
return false;
}
int maxLookup = (int) Math.sqrt(n);
for (int i = 3; (i+2) <= maxLookup; i = i + 6) {
if (n % (i+2) == 0 || n % (i+4) == 0) {
return false;
}
}
return true;
}
You could also use some simple Math property for this in your for loop.
A number 'n' will be a prime number if and only if it is divisible by itself or 1.
If a number is not a prime number it will have two factors:
n = a * b
you can use the for loop to check till sqrt of the number 'n' instead of going all the way to 'n'. As in if 'a' and 'b' both are greater than the sqrt of the number 'n', a*b would be greater than 'n'. So at least one of the factors must be less than or equal to the square root.
so your loop would be something like below:
for(int i=2; i<=Math.sqrt(n); i++)
By doing this you would drastically reduce the run time complexity of the code.
I think it would come down to O(n/2).
One of the fastest way is looping only till the square root of n.
private static boolean isPrime(int n){
int square = (int)Math.ceil((Math.sqrt(n)));//find the square root
HashSet<Integer> nos = new HashSet<>();
for(int i=1;i<=square;i++){
if(n%i==0){
if(n/i==i){
nos.add(i);
}else{
nos.add(i);
int rem = n/i;
nos.add(rem);
}
}
}
return nos.size()==2;//if contains 1 and n then prime
}
You are checking i<=n.So when i==n, you will get 0 only and it will return false always.Try i<=(n/2).No need to check until i<n.
The mentioned above algorithm treats 1 as prime though it is not.
Hence here is the solution.
static boolean isPrime(int n) {
int perfect_modulo = 0;
boolean prime = false;
for ( int i = 1; i <= n; i++ ) {
if ( n % i == 0 ) {
perfect_modulo += 1;
}
}
if ( perfect_modulo == 2 ) {
prime = true;
}
return prime;
}
Doing it the Java 8 way is nicer and cleaner
private static boolean isPrimeA(final int number) {
return IntStream
.rangeClosed(2, number/2)
.noneMatch(i -> number%i == 0);
}
I want to tell if an array of integers is alternating.
in JAVA.
For example:
a[]={1,-1,1,-1,1,-1} --> true
a[]={-1,1,-1,1,-1} --> true
a[]={1,-4,1-6,1} --> true
a[]={1,1,1,14,5,3,2} --> false
I have started to write some code that uses flags. For example if the current_is_positive=0 and else = 1, but I'm not getting anywhere. What is a good way to achieve this effect?
I think you mean alternating in sign, i.e. positive number, negative number, positive number, etc.?
You could use the following strategy:
Skip the first element.
For every other element, compare its sign with the sign of the previous element:
If they're different, the sequence is still alternating upto now - you should continue.
If they're the same sign, the sequence is not alternating. You can stop processing at this point.
As this sounds like a homework assignment, I'll leave it upto you to write the appropriate code in Java.
Here my solution:
This checks that element n+1 is the inverse of the element n.
public static void main(String[] args) {
int[] ints = {1, -1, 2, -1};
System.out.println(new Example().isArrayAlternating(ints));
}
public boolean isArrayAlternating(int[] ints) {
if (ints == null || ints.length % 2 != 0) {
return false;
}
for (int i = 0; i < ints.length - 1; i++) {
if (ints[i] != ints[i + 1]*(-1)) {
return false;
}
}
return true;
}
If you only wanted to check for positive number, negative number...n times, without paying attention to value:
public static void main(String[] args) {
int[] ints = {1, -1, 2, -1};
System.out.println(new Example().isArrayAlternating(ints));
}
public boolean isArrayAlternating(int[] ints) {
if (ints == null || ints.length % 2 != 0) {
return false;
}
for (int i = 0; i < ints.length - 1; i++) {
if (ints[i] >= 0 && ints[i + 1] >= 0 || ints[i] <= 0 && ints[i + 1] <= 0) {
return false;
}
}
return true;
}
You can simply check if all items are equal to the item two steps back. I don't know what language you are using, but for example using C# you could do it like this:
bool alternating = a.Skip(2).Where((n, i) => a[i] == n).Count() == a.Length - 2;
Edit:
So you want to check if the sign of the values are alternating, not the values?
Then just check the sign against the previous item:
bool alternating = a.Skip(1).Where((n,i) => Math.Sign(n) == -Math.Sign(a[i])).Count() == a.Length-1;
boolean prevPositive = arr[0] > 0, error = false;
for (int i = 1; i < arr.length; ++i) {
boolean current = arr[i] > 0;
if (current != prevPositive) {
current = prevPositive;
} else {
error = true;
break;
}
}
if (error)
System.out.println("No");
else
System.out.println("Yes");
private enum SIGN {
POSITIVE, NEGATIVE
};
public static boolean isAlternating(int... ints) {
SIGN last = null;
for (int i : ints) {
if (i >= 0) {
if (last == null) {
last = SIGN.POSITIVE;
} else {
if (last == SIGN.POSITIVE) {
return false;
} else {
last = SIGN.POSITIVE;
}
}
} else {
if (last == null) {
last = SIGN.NEGATIVE;
} else {
if (last == SIGN.NEGATIVE) {
return false;
} else {
last = SIGN.NEGATIVE;
}
}
}
}
return true;
}
Run through the array from index 1 till the end.
At each index, evaluate (a[i] > 0) == (a[i-1] > 0). If this is true, then your array is not alternating.
If you make it till the end without concluding it is not alternating, then it is alternating :)
Run a loop, from first index to maximum possible with a step of 2, to check for same sign.
Then again a loop, from 2nd index to maximum possible with a step of 2, to check for opposite sign, but all same.
So, loop from index - 0, 2, 4, 6, ...
then loop from index - 1, 3, 5, 7, ...
Then check that the multiplication of every number in both loop with the first number in that iteration should be positive.
int a[]={1,-1,1,-1,1,-1};
boolean alternating = true;
for (int i = 0; i < a.length; i = i + 2) {
if (a[i] * a[0] > 0) {
} else {
alternating = false;
}
}
for (int i = 1; i < a.length; i = i + 2) {
if (a[i] * a[1] > 0) {
} else {
alternating = false;
}
}
if (alternating) {
System.out.println("Array is alternating");
} else
System.out.println("Array is not alternating");
}
For i = 2 to n
check whether A[i-1] && A[i] are with diff sign..
in C++; return ((A[i-1] ^ A[i]) < 0).
Same explained here : http://www.youtube.com/watch?v=Z59REm2YKX0
EDIT
If an integer is negative, then the high order bit is 1. Otherwise, it's 0. You can check if two integers have different signs by XORing them together. If the signs are different, then the high order bit of the result will be 1. If they're the same, then the high order bit will be 0. Thus,
A XOR B < 0 is equivalent to "A and B have different signs"
Peter Ruderman