Comparison for BigInteger not working - java

I'm not getting the output that I'm expecting. This is for a primality test. I'm not really sure what's wrong. Either my loop isn't working correctly, or this isn't.
n is a BigInteger. It's a random generated by user inputted length.
public static boolean isPrime(BigInteger n) {
BigInteger zero = new BigInteger("0");
BigInteger one = new BigInteger("1");
BigInteger two = new BigInteger("2");
BigInteger three = new BigInteger("3");
System.out.println(n + " Mod 2 " + n.mod(two));
if (n.compareTo(one) == 0 || n.compareTo(one) < 0) {
//System.out.println("HIT1");
return false;
} else if (n.compareTo(three) == 0 || n.compareTo(three) < 0) {
//System.out.println("HIT2");
return false;
} else if ((n.mod(two)).compareTo(zero) == 0 || (n.mod(three)).compareTo(zero) == 0) {
//System.out.println("HIT3");
return false;
} else {
System.out.println("Heres n : " + n);
return true;
}
}
Here's my loop. I know for sure that my number generator works though.
do {
num1 = generateNumber(p);
} while (isPrime(generateNumber(p)) == false);
do {
num2 = generateNumber(q);
} while (isPrime(generateNumber(q)) == false);

Don't test if the result of compareTo() equals -1. When you want to mean a < b, you should write a.compareTo(b) < 0. Always compare with 0, not any other constant.

Just realized what the issue was. I'm generating two different numbers in the loop and inside the loop. I was also incorrectly assigning the BigInteger incorrectly in the loop. I should be doing
num1 = new BigInteger(generateNumber(p).toString());

First, test if the number is 2 (if it is, then it is prime). Next, test if the number is divisible by 2 (if it is, then it is not prime). Next, iterate from 3 to the square root of the number in increments of 2 testing for divisibility with the original number (if it is, then it is not prime). Otherwise, the number is prime. Something like,
public static boolean isPrime(BigInteger n) {
final BigInteger two = new BigInteger("2");
if (n.equals(two)) {
return true;
}
if (n.mod(two).equals(BigInteger.ZERO)) {
return false;
}
for (BigInteger i = two.add(BigInteger.ONE); i.multiply(i).compareTo(n) < 1;
i = i.add(two)) {
if (n.mod(i).equals(BigInteger.ZERO)) {
return false;
}
}
return true;
}

Related

Object oriented programming comparing linkedlists

I have objects of class Bit which is basically a class that has one field called value and it's boolean.
public class Bit {
private boolean value;
public Bit() {
this.value = false;
}
public Bit(boolean value) {
this.value = value;
}
public boolean getValue() {
return value;
}
}
and it has some more methods.
and then I have a class called number which is supposed to represent large number in their binary representation using a linked list where the firstlink is the LSB and the lastlink is the MSB.
for instance if I call the constructor
Number num1 = new Number(6);
then I'll have a linked list like the following : 0 1 1 (null)
Now I wanna know how to be able to compare two Number objects.
so for example: if I have num1, and Number num2 = new Number (7); [ 1 1 1 ]
then I want a method to tell me that num2 is larger than num1
to compare two binary numbers simply I would start with the MSB and compare each bit and once one is larger than the other that means the number is larger.
I could easily get the integer value of each Link(Bit) using Bit.toInt();
So I was thinking of iterating over the list and comparing the bits one by one , problem is that my iterator stars before firstlink (LSB) , I know I could move it all the way to the end and start iterating using hasPrevious() but I don't have that method.
I wanna be able to do that while only going over each list once.
Any ideas?
public static boolean lessEq(Number num1, Number num2){
Iterator<Bit> it1 = num1.bitIterator().;
Iterator<Bit> it2 = num2.bitIterator();
}
Number constructors:
public Number(){
list = new LinkedList<Bit>();
list.add(new Bit(false));
}
/**
* Constructs a new Number from an int.
* #param number an int representing a decimal number
*/
public Number(int number) { // assignment #1
list = new LinkedList<Bit>();
if(number == 0) list.add(new Bit(false));
if (number < 0) throw new IllegalArgumentException("number cannot be negative");
else {
while (number > 0) {
if (number % 2 == 0) {
list.add(new Bit(false));
}else list.add(new Bit(true));
number = number / 2;
}
}
}
Edit: it Works Thanks very much for the comments !
Initially you assume that both numbers are equal.
You get bits from both numbers. Use zero if either was exhausted.
If both bits are equal, you don't alter the result.
If bit from number A is 1, then set number A to be larger.
If bit from number B is 1, then set number B to be larger.
If both lists are exhausted, return result.
Otherwise repeat from step 2.
This takes into account the case where you allow lists with unnecessary zero bits as MSB.
If you want to submit fancy homework you can start from the end, keep track of the index you're at and stop at the first comparison where the bits are not equal.
You can do an obvious thing: collect the bits in an array, then walk the two arrays backwards. Or, you can use recursion, and use the stack for storage:
public int compareTo(Number other) {
Iterator<Bit> it1 = this.bitIterator();
Iterator<Bit> it2 = other.bitIterator();
return bitCompareTo(it1, it2);
}
private static int bitCompareTo(Iterator<Bit> it1, Iterator<Bit> it2) {
if (!it1.hasNext() && !it2.hasNext()) return 0;
boolean b1 = it1.hasNext() ? it1.next().getValue() : false;
boolean b2 = it2.hasNext() ? it2.next().getValue() : false;
int cmp = bitCompareTo(it1, it2);
if (cmp != 0) return cmp;
else return Boolean.compare(b1, b2);
}
This traverses each iterator only once, but since the comparison logic is after the recursive call, you get the comparisons done as they are popped off the call stack - in reverse order, just like we want them.
Basically: If we reach the end of both iterators at the same time, we're undecided on length alone, and signal that with 0, and we kick off our recursive decision-making. (If we reach the end of one iterator sooner, we assume false to left-pad that number with zeroes.) In each recursive step, if we've decided (whether on length or on a higher bit pair), we just pass that decision along. If the higher bits were undecided, we try to compare the current bit pair (and if it's equal, Boolean.compareTo will return 0, telling the next level down that we're still undecided). If we inspected all bits and we're still undecided, we'll just say 0 now stands for "equal" - precisely what compareTo should return in that case.
Once you have compareTo, it is trivial to define the other relational operators.
I think you should try this:
public static boolean lessEq(Number num1, Number num2) {
LinkedList<Bit> bits1 = num1.list;
LinkedList<Bit> bits2 = num2.list;
if(bits1.size() == bits2.size()) {
for(int i = bits1.size() - 1; i >= 0; i++) { // reversed loop since the MSB is at the end of the list
Bit bit1 = bits1.get(i);
Bit bit2 = bits2.get(i);
if(bit1.getValue() != bit2.getValue()) {
if(bit1.getValue()){ // can be replaced with return !bit1.getValue() if you want
return false; // bit1's actual bit is true, bit2 is false, so bit1 is greater
} else {
return true;
}
}
}
return true; // all bits are the same
} else {
if(bits1.size() > bits2.size()) { // can be replaced with return bits1.size() <= bits2.size() if you want
return false; // first number has more elements, so it's greater
} else {
return true;
}
}
}
EDIT
According to comments you can do the following instead (using iterators)
public static boolean lessEq(Number num1, Number num2) {
Iterator<Bit> bits1 = num1.list.descendingIterator();
Iterator<Bit> bits2 = num2.list.descendingIterator();
while(bits1.hasNext() && bits2.hasNext()){
Bit bit1 = bits1.next();
Bit bit2 = bits2.next();
if(bit1.getValue() != bit2.getValue()) {
return !bit1.getValue();
}
}
return bits2.hasNext();
}
There’s no real problem in comparing from the least significant bit. You just need to keep track of the difference found so far, and discard it if you find a difference on a higher-order (more significant) bit. It’s easiest to do it recursively:
public class Number implements Comparable<Number> {
/** Linked list of bits, least significant bit first */
Node lsb;
public Number(int n) {
if (n < 0) {
throw new IllegalArgumentException("Negative numbers not supported, got " + n);
}
if (n == 0) {
lsb = null;
} else {
lsb = new Node(new Bit(n % 2 != 0));
n /= 2;
Node tail = lsb;
while (n > 0) {
Node newNode = new Node(new Bit(n % 2 != 0));
n /= 2;
tail.setNext(newNode);
tail = newNode;
}
}
}
#Override
public int compareTo(Number other) {
return compare(lsb, other.lsb, 0);
}
private int compare(Node left, Node right, int diffSoFar) {
if (left == null) {
if (nonZero(right)) {
return -1;
} else {
return diffSoFar;
}
}
if (right == null) {
if (nonZero(left)) {
return 1;
} else {
return diffSoFar;
}
}
int localDiff = Boolean.compare(left.getData().getValue(), right.getData().getValue());
if (localDiff != 0) {
diffSoFar = localDiff;
}
return compare(left.getNext(), right.getNext(), diffSoFar);
}
private boolean nonZero(Node list) {
if (list == null) {
return false;
}
if (list.getData().getValue()) {
return true;
}
return nonZero(list.getNext());
}
}
Example use:
Number six = new Number(6);
Number seven = new Number(7);
System.out.println("Comparing 6 and 7: " + six.compareTo(seven));
System.out.println("Comparing 15 and 6: " + new Number(15).compareTo(six));
Output:
Comparing 6 and 7: -1
Comparing 15 and 6: 1
I am assuming the following Node class:
public class Node {
private Node next;
private Bit data;
// Constructor, getters, setters
}

Getting weird output while finding prime number in java

I have two methods to find out prime number in java method - 2 working fine but getting wrong output from method one, can any help me where i did wrong in logic. Thanks in advance
My entire code
package prepare;
import java.util.Scanner;
public class Squar {
//Method - 1 to find prime number
boolean isPrime(int num){
int exp = (int)Math.sqrt(num);
for(int i=2;i<exp;i++){
if(exp%2==0){
return false;
}
}return true;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
Squar s = new Squar();
System.out.println("From M1 "+s.isPrime(num));
scan.close();
System.out.println("From M2 "+s.isPrimeNumber(num));
}
//Method - 2 to find prime number
public boolean isPrimeNumber(int number) {
if(number == 1){
return false;
}
if (number == 2 || number == 3) {
return true;
}
if (number % 2 == 0) {
return false;
}
int sqrt = (int) Math.sqrt(number) + 1;
for (int i = 3; i < sqrt; i += 2) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
for input : 63 actual out put would be false in prime number but getting
different output from method one
output
63
From M1 true
From M2 false
In isPrime() method, Shouldn't you be checking num % i == 0 rather than exp % 2 == 0?
Change isPrime function like this.
boolean isPrime(int num) {
int exp = (int) Math.sqrt(num);
for (int i = 2; i < exp; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
Because in if condition you are checking exp%2 == 0 . But this statement does not change when iterating on i < exp. So this logic should be on with num % i == 0
Have a look at this line of your code
if(exp%2==0){
it should be num % i
Well I think the culprit is
if(exp%2==0){
and it is causing a problem while iterating i<exp.So you may want to tweak it to
num%i==0
I have tried to give a few other approaches to this issue.
I hope that would be helpful.
I think there is a reason that tempted you to use
(int)Math.sqrt(num);
I have tried to elaborate it below.
Consider below 3 approaches.
All of them are correct but the first 2 approaches have some drawbacks.
Approach 1
boolean isPrime(int num) {
for(int i=2;i<num;i++) {
if(num%i==0)
return false;
}
return true;
}
We have a scope to make it faster.
Consider that if 2 divides some integer n, then (n/2) divides n as well.
This tells us we don't have to try out all integers from 2 to n.
Now we can modify our algorithm:
Approach 2
//checks whether an int is prime or not.
boolean isPrime(int num) {
for(int i=2;2*i<num;i++) {
if(num%i==0)
return false;
}
return true;
}
Finally, we know 2 is the "oddest" prime - it happens to be the only even prime number.
Because of this, we need only check 2 separately, then traverse odd numbers up to the square root of n.
I think this might have tempted you to use (int)Math.sqrt(num);
Approach 3
//checks whether an int is prime or not.
boolean isPrime(int num) {
//check if num is a multiple of 2
if (num%2==0) return false;
//if not, then just check the odds
for(int i=3;i*i<=num;i+=2) {
if(num%i==0)
return false;
}
return true;
}
Hence, we've gone from checking every integer (up to n to find out that a number is prime) to just checking half of the integers up
to the square root.
Is it not an improvement, especially considering when numbers are large.
Well, your first algorithm is almost (replace %2 with %i) correct. I do not know the second algorithm, but i would definitely change it to this form:
public boolean isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i < Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}

Any efficient way to determine there is more N continuous true in a boolean array? In Java

Example:
I have a boolean array with N boolean inside. Which is the most efficient way to determine there are more than continuous M true flags, in the array?
Write some thing like (bA=booleanArray, for M=3)
(bA[0] && bA[1] && bA[2]) || (bA[1] && bA[2] && bA[3]) || ...
is really ugly.
And this can not be done with a VERY-LONG dynamic length array with dynamic least true flags to meet need. And maybe inefficient with few and scattered true?
Use a loop and a counter:
int count = 0;
for (boolean x: theArray){
if (x) {
count++;
if (count >= n) return true; // n is the count we are looking for
} else { count = 0; }
}
return false;
This is one approach, that allows for adjusting the number of consecutive entries, and the array is not fixed in length. The method hasConsecutiveTrue will loop over the array, looking for a value of true. If found, it increments the counter, otherwise sets it to 0. If the counter matches the expected amount, it returns true. Otherwise, it will return false. EDIT: based upon a comment, make so it will throw an IllegalArgumentException for an attempt to find <= 0 consecutive numbers, or if the input array is null/empty.
public static void main(String[] args)
{
int consecutive = 3;
boolean[] ba = new boolean[] { true, false, true, true, true, false};
System.out.println("found: " + hasConsecutiveTrue(ba, consecutive));
}
private static boolean hasConsecutiveTrue(boolean[] ba, int consecutive) throws IllegalArgumentException
{
// we will not attempt to process if the input <= 0; if 0 should return
// true, then modify the conditional statement as appropriate
if (consecutive <= 0) {
throw new IllegalArgumentException("Invalid input for consecutive: " +
consecutive);
}
if (ba == null || ba.length < 1) {
throw new IllegalArgumentException("No array to check!");
}
int count = 0;
boolean found = false;
for (boolean b : ba) {
count = ( b ? count + 1 : 0);
if (count == consecutive) {
found = true;
break;
}
}
return found;
}
Here's one using BitSet: if you're able to start with a BitSet, it will almost certainly be more efficient. If you have to convert from a boolean[] or byte[], it might not be.
// BitSet bits = BitSet.valueOf(bA);
int i = bits.nextSetBit(0);
while (i > -1 && i < bits.length()) {
int nextFalse = bits.nextClearBit(i);
if (nextFalse - nextTrue > N) return true;
i = bits.nextSetBit(nextFalse) + 1;
}
return false;
One option is to use a string with T + F in the location to determine the true/false setting of your array. Then use contains.
Example:
String booleanArray = "TTFFTFTFTFTTTFFT";
if ( !booleanArray.contains("TTT") ) // Pattern was found.

Method to check if number is symmetric in Java [duplicate]

This question already has answers here:
How do I check if a number is a palindrome?
(53 answers)
Closed 9 years ago.
I need help with a method to check if a number is symmetric, so from what I understand I need to check equality between all the numbers and to make sure there is no different number amounts them...right?
This is my code:
public boolean isSemetric (int number) {
int temp;
boolean answer = true;
while (number != 0) {
temp = number % 10;
number /= 10;
if (temp != (number%10)) {
answer = false;
} else {
answer = true;
}
}
return answer;
}
I'm kind of new to programming so be forgiven to my code :/
Thanks!
As peter.petrov pointed out in the comment section of your question, your method as it's written will always return false, except for when number is equal to 0. The reason for this can be seen when you pass in a number like 111 and step through the code in a debugger. The final iteration will fail because number /= 10 will result in 0, and temp will be 1, which fails your test.
If you are indeed looking to identify palindromes, consider the following approach that should be simple to implement
1. copy number into temp
2. convert temp to a String, and reverse it (tmpStr)
3. convert tmpStr back to an integer (reversedInt)
4. compare number and reversedInt for equality
viola. Not the most efficient algorithm, but its easy to understand and gets the job done.
I would do it like this (I don't want to use String here and I don't want to use local array variable for the digits).
public static boolean isSymmetric (long number) {
if (number == 0) return true;
else if (number < 0) return false;
long DEG_10 = (long)(Math.pow(10, (int)Math.log10(number)));
while (number > 0){
long dStart = number / DEG_10;
long dEnd = number % 10;
if (dStart != dEnd) return false;
number = (number - dStart * DEG_10 - dEnd) / 10;
DEG_10 /= 100;
}
return true;
}
This is the easiest approach I can think of - Get the String value of the number, if the reverse is the same then it is symmetrical.
// Symmetry
public static boolean isSymmetric(int number) {
String val = String.valueOf(number); // Get the string.
StringBuilder sb = new StringBuilder(val);
return (val.equals(sb.reverse().toString())); // if the reverse is the same...
}
Here's a somewhat fixed up version of your code. However, it checks if all numbers are the same, e.g. 5555 or 111. 11211 would return false.
public boolean areAllDigitsTheSame (int number) {
int temp;
boolean answer = true;
while (number >= 10) {
temp = number % 10;
number /= 10;
if (temp != (number%10)) {
return false
}
}
return true;
}
Edit: The C++ answer in the linked question works by constructing the reverse number gradually in the loop, and finally checking if they're the same. This is a similar to what you are doing.
Here's another version for fun:
public boolean isPalindrome (int number) {
int reversedNumber = 0;
while (number > 0) {
int digit = number % 10;
reversedNumber = reversedNumber*10 + digit;
if (reversedNumber == number) { // odd number of digits
return true;
}
number /= 10;
if (reversedNumber == number) { // even number of digits
return true;
}
}
return false;
}

Very simple prime number test - I think I'm not understanding the for loop

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);
}

Categories

Resources