Recently, I've been attempting to create a program that prints prime numbers until a user-specified integer is achieved, the program itself including a "PrimeCheck" class, a "PrimeSieve" class of sorts, and a "Main" class:
public class PrimeCheck {
boolean result;
public PrimeCheck() {
result = true;
}
public boolean primeCheck (int num) {
int i, num1 = num - 1;
for (i = num1; i > 1; i--) {
if (num % i == 0) {
result = false;
}
}
return result;
}
}
import java.util.ArrayList;
public class PrimeSieve {
public PrimeSieve() {
}
PrimeCheck PCObj = new PrimeCheck();
ArrayList<Integer> primes = new ArrayList<Integer>();
public void primeSieve(int num) {
int[] arr = new int[num];
for (int i = 0; i < num; i++) {
arr[i] = i + 1;
if (PCObj.primeCheck(arr[i]) == true) {
primes.add(arr[i]);
}
}
for (int c = 0; c < primes.size(); c++) {
System.out.print(primes.get(c) + " ");
}
}
}
import java.util.Scanner;
public class PrimeSieveMain {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
PrimeSieve PSObj = new PrimeSieve();
System.out.println("Prime Sieve");
System.out.print("Limit: ");
int limit = input.nextInt();
PSObj.primeSieve(limit);
}
}
Pardon my inexperience, yet I cannot seem to locate the problem in this program.
Your problem is in the PrimeCheck class. That class has a state variable (a field) named result. State variables retain the value between calls, for as long as the object is "alive".
So as soon as you hit a number that is not prime, you set this result to false. That value is kept and never changes.
The result variable should be a local variable, not a state variable, and it should be set to true at the beginning of the method. This way it will start fresh every time.
Other notes:
There is really no point in the PrimeCheck class. It doesn't represent a real "entity", and the method can easily be added to the PrimeSieve class. Creating classes for different entities is a good practice, but I think in this case there is no point - it just has one function and that function doesn't depend on anything but its parameters.
If you meant to represent the Sieve of Eratosthenes then this is not the correct algorithm. This is the naive algorithm - it just tests each number individually and doesn't cross out multiples of previous primes as the real Sieve does.
The PrimeCheck has serveral design problems, the first is you designed the result variable as a member, and its only initialized to true upon construction, but updated with false in primeCheck(). Once it has returned false, it will return false on all subsequent calls.
Its also not necessary to design the result as a member, since the result is only related to the method primeCheck(), thus change it to return the value directly, eliminating the member:
public class PrimeCheck {
public boolean primeCheck (int num) {
for (int i = num - 1; i > 1; i--) {
if (num % i == 0) {
return false;
}
}
return true;
}
}
Since PrimeCheck now has no state left, the method could also be made static, making the PrimeCheck instance in your program superflous. You could just call the static method.
PrimeCheck is also terribly inefficient, due to several design choices - one is you start testing from (num - 1), but the most common divisors are the smallest numbers. So it would be more efficient to start testing from the lower end and work the loop upwards. The upper bound (num - 1) is also chosen poorly. The possible largest divisor for num is the square root of num, so the upper bound should be that.
When you get the number is not a prime:
public boolean primeCheck (int num) {
int i, num1 = num - 1;
for (i = num1; i > 1; i--) {
if (num % i == 0) {
result = false;
}
}
return result;
}
result become false, and never change, so I suggest this:
public boolean primeCheck (int num) {
result=true;
int i, num1 = num - 1;
for (i = num1; i > 1; i--) {
if (num % i == 0) {
result = false;
}
}
return result;
}
Before you start to determine prime, you should presume it is a prime
Not tested, just an idea
Related
I'm learning Java, and I'm stuck on a recursion problem.
I need to use a recursive method to check if a number is an Armstrong number or not.
My code:
public class ArmstrongChecker {
public boolean isArmstrong(int number) {
// check if the number is a negative number
if (number < 0) {
return false;
}
ArmstrongChecker armstrongChecker = new ArmstrongChecker();
// find the length of the number
int length = armstrongChecker.lengthChecker(number);
// create a variable to store the sum of the digits of the number
int sum = 0;
// find the individual digits and raise to the power of the numbers of digits
if (number != 0) {
int digit = Math.floorMod(number, 10);
int powerRaised = (int) Math.pow(digit, length);
sum = sum + powerRaised;
isArmstrong(number / 10);
}
return sum == number;
}
// method to check the length of the number
public int lengthChecker(int number) {
int length = String.valueOf(number).length();
return length;
}
}
How do I prevent int length in isArmstrong() method from changing its value.
While you are not changing it's value in the posted code, you could mark that variable to be a constant. This way the compiler can error out if you tried to assign a new value.
final int length = armstrongChecker.lengthChecker(number);
As I've already said in the comments, your solution has the following issues:
The result of the recursive call isArmstrong() is being ignored;
There's no need for spawning new instances of ArmstrongChecker. And this method doesn't require object creation at all, it can be implemented as static.
Checking if the number is an Armstrong number boils down to calculating its Armstrong sum, the solution will be cleaner if you implement only this part using recursion.
It might look like this:
public static boolean isArmstrong(int number) {
if (number < 0) return false;
if (number < 10) return true;
return number == getArmstrongSum(number, String.valueOf(number).length());
}
public static int getArmstrongSum(int number, int power) {
if (number == 0) {
return 0;
}
return (int) Math.pow(number % 10, power) + getArmstrongSum(number / 10, power);
}
main()
public static void main(String[] args) {
System.out.println(isArmstrong(370)); // true
System.out.println(isArmstrong(12)); // false
System.out.println(isArmstrong(54)); // false
System.out.println(isArmstrong(153)); // true
}
Output:
true
false
false
true
You need to get the length once for whole recursion, so the cleanest approach would be to pass down both the number and the length into the recursion. An easy way to do this is to have one method that is the public face of the API, and another that does the recursion.
public class ArmstrongChecker {
public boolean isArmstrong(int number) {
if (number < 0) {
return false;
}
int length = lengthChecker(number);
int sum = armstrongSum(number, length);
return sum == number;
}
private int armstrongSum(int number, int length) {
int sum = 0;
if (number != 0) {
int digit = Math.floorMod(number, 10);
int powerRaised = (int) Math.pow(digit, length);
sum += powerRaised;
sum += armstrongSum(number / 10, length);
}
return sum;
}
public int lengthChecker(int number) {
int length = String.valueOf(number).length();
return length;
}
}
This is pretty common in recursion, where the parameters to the recursive part of the algorithm are a little different (usually there are more of them) than what you want a client of the API to have to pass in. The number changes in each recursive call, where number / 10 is passed down, but the same length is passed all the way through.
Notice that the recursive armstrongSum uses the return value from the recursive call, and that there is no need to create another instance of ArmstrongChecker when you are already in an instance method of the class.
I am trying to write a small method which will calculate the exponent given a number and power (I know about math.pow I am just doing this for kicks). However the loop inside my method never starts and I cant figure out why. My code is below, all help appreciated.
public static void main(String[] args) {
int result = exponantCalculation(2, 3);
System.out.println(result);
}
public static int exponantCalculation(int number, int power) {
for (int i = 1;i >= power;i++) {
number = number * number;
}
return number;
}
You've used the wrong comparison operator in the loop condition (>=, should be <= or < — see other answers).
Not sure, maybe this was intentional, BUT if the method is meant to calculate "number to the power of power", then you're incorrectly squaring the result of the previous iteration. This will produce a much higher value that the number to the power of power.
You need to introduce a new variable and multiply it with number in the loop, e.g.
long result = 1;
for (int i = 0; i < power; i++) {
result *= number; // same as "result = result * number"
}
return result;
Minor note: I've intentionally used long type for the result, which can slightly defer the integer overflow problem for big values.
Condition inside for loop is wrong.
Since you are passing 3 as power in your method as parameter, i is initialized with 1 and then condition gets checked whether i>=power with is obviously not true in this case so your loop never starts.
Change
for (int i = 1;i >= power;i++)
to
for (int i = 1;i <= power;i++)
if you wish to calculate the power of any number, you can use following method
public static int exponantCalculation(int number, int power) {
int result = 1;
for (int i = 1;i <= power;i++) {
result = result * number;
}
return result;
}
The for loop condition was wrong, but also you need to sotre the result in another variable:
public static int exponantCalculation(int number, int power) {
if(power == 0){
return 1;
}
int result = 1;
for (int i = 1;i <= power;i++) {
result *= number;
}
return result;
}
I have got the code working, it is a prime factorization method class and tester. It prints out the code fine but I am forced to return a zero value, because the method is an Integer method.
public class FactorGenerator{
private int num;
public FactorGenerator(int numberToFactor){
num = numberToFactor;
}
public int nextFactor(){
for(int i = 2; i <= num;){
if (num%i==0){
num = num/i;
System.out.println(i);
}
else{
i++;
}
}
return 0;
}
public boolean hasMoreFactors(){
for(int i = 1; i < num; i++){
if(num % i == 0){
return true;
}
}
return false;
}
}
And this is the tester I am using, which cannot be changed, and must stay the same:
import java.util.Scanner;
public class FactorPrinter{
public static void main(String [] args){
Scanner in = new Scanner(System.in);
System.out.print("Enter a number to Factor:");
int numberToFactor = in.nextInt();
System.out.println("You chose: "+numberToFactor+" to factor.");
FactorGenerator fg = new FactorGenerator(numberToFactor);
while (fg.hasMoreFactors())
System.out.println(fg.nextFactor());
}
}
When I input 150, it prints 2,3,5,5,0
Is there anyway to remove the 0?
Don't print the factors in nextFactor(). Return them.
public int nextFactor() {
for (int i = 2; ; i++) {
if (num % i == 0) {
num /= i;
//System.out.println(i);
return i;
}
}
}
The test num % i == 0 is guaranteed to return true eventually, so if you remove the i <= num test from the for loop the compiler won't require you to add return 0 at the end.
All required prints are done in nextFactor. So just don't print the return code. Change this:
System.out.println(fg.nextFactor());
by this:
fg.nextFactor();
That said, the nextFactor name is then ill-named. Even if it yields the result, the name suggests that it's a generator which should return each factor at each call, the memory effect being provided by the num member method.
So doing what I'm advising works, but it may not be in the spirit of the problem. John's answer would be better if you have to examine/store the factors, not only print them.
Your hasMoreFactor() method should have returned false by the time it has been invoked four times (and nextFactor returned 2, 3, 5, 5, respectively) and is invoked the fifth time.
I'm currently working on a program in which the user inputs a number, and the program will give you the number of prime numbers up to that number. Although there are no errors, the program always outputs the same number: 3. This is the code:
public static int Prime(int num){
boolean isPrime = true;
int count = 0;
for (int a = 2; a <=num; a++){
for (int i = 2; i <= a/2; i++){
if (a == 2 || a == 3 || a == 5){
isPrime = true;
}
else if (a % i == 0){
isPrime = false;
}
}
if (isPrime == true)
count++;
}
return count;
}
In your inner for loop, you are setting isPrime, but then you keep looping. Subsequent loops may set isPrime to false if a candidate divisor i doesn't divide cleanly. Only 2, 3, and 5, the 3 numbers in your first if condition, set it to true always, so you always get 3.
Instead, set isPrime to true at the beginning of the inner for loop, and break out of the inner for loop after each time you set isPrime. If the number is 2, 3, or 5, set to true and break so nothing can set it to false, so you can count it. If you found a factor, it's not prime, so set to false and break so nothing can set it to true and it's not counted.
Incidentally, your final if condition tests a boolean; it can be simplified to if (isPrime).
Your strategy is to test each number from 2 through num for primality by scanning for factors other than itself and 1. That's ok, albeit a bit simplisitic, but your implementation is seriously broken.
An approach involving scanning for factors implies that you start by guessing that the number being tested is prime, and then go looking for evidence that it isn't. You've missed the "guessing it's prime" part, which in your particular code would take the form of setting isPrime to true at the beginning of your outer loop.
Your code, on the other hand, never resets isPrime to true after testing the case of a == 5. That variable will be set to false when testing the case of a == 6, and will remain so for the duration. That is why you always get the result 3 for any input greater than 4.
If you properly reset isPrime in the outer loop then you can also remove the first part of the conditional in the inner loop, as it will be redundant. It is anyway never executed in the cases of a == 2 and a == 3 because the inner loop performs zero iterations in those cases.
Note also that it would be more efficient to break from the inner loop as soon as you determine that a is composite, and that you run more iterations of that loop than you need to do for primes (it would be sufficient to loop until i exceeds the square root of a; that is, until i * i > a).
Finally, note that this problem would be more efficiently implemented via the Seive of Eratosthenes (or one of the other prime number seives) as long as the numbers you want to test are not so large that the needed array would be prohibitively large.
I simplified your code by reducing number of operations which is needed to check if a is 2, 3, or 5.
public static int Prime(int num) {
int count = 0;
if (num >= 2) {
count++; // One optimization here
}
for (int a = 3; a <= num; a+=2) { // Another one here as we don't have any even number except 2 :D
boolean isPrime = true;
for (int i = 2; i <= a / 2; i++) {
if (a % i == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
count++;
}
}
return count;
}
#include <iostream>
using namespace std;
int numberOfPrimes(int num)
{
if(num==2)
return 1;
else if(num<2)
return 0;
int prime=1;
for(int i=3;i<=num;i++)
{
for(int j=2;j<=(i/2)+1;j++)
{
if(i%j==0)
break;
if(j==(i/2)+1)
prime++;
}
}
return prime;
}
package com.amit.primenumber;
public class PrimeNumber {
public static void main(String[] args) {
long number=23L;
String message=null;
PrimeNumber primeNumber = new PrimeNumber();
boolean result = primeNumber.primeNumber(number);
if(result){
message="a Prime Number";
}else{
message="Not a Prime Number";
}
System.out.println("The given "+number+" number is "+message);
}
public boolean primeNumber(long number){
for(long i=2;i<=number/2;i++){
if(number%i==0){
return false;
}
}
return true;
}
}
package basics;
public class CheckPrimeOrNot {
public void checkprimeNumber(int i){
int flag=0;
if(i>2){
for(int j = 2; j <= i/2; j++){
if(i%j == 0){
System.out.println("Given number is Not Prime");
flag=1;
break;
}
}
if(flag==0){
System.out.println("Given number is Prime");
}
} else{
System.out.println("Please enter a valid number");
}
}
public static void main(String[] args) {
CheckPrimeOrNot CheckNumber = new CheckPrimeOrNot();
CheckNumber.checkprimeNumber(11);
CheckNumber.checkprimeNumber(0);
CheckNumber.checkprimeNumber(250365);
CheckNumber.checkprimeNumber(1231);
}
}
public class newClass {
public static void main(String[] args)
{
int nullValue=0;
int nullValue2=1;
int nullValue3=0;
int nullValue4=0;
int [] sourceArray = {4,5,6,7};
int [] targetArray = new int [4];
for (int i=0; i<sourceArray.length; i++)
{
nullValue+=sourceArray[i];
}
targetArray[0]=nullValue;
// I added all sourceArray elements together and passed it to targetArray[0]
for (int i=0; i<sourceArray.length; i++)
{
nullValue2*=sourceArray[i];
}
targetArray[1]=nullValue2;
// I multiplied all sourceArray elements together and assigned the result to targetArray[1]
for (int i=0; i<sourceArray.length; i++)
{
nullValue3 += getResult(sourceArray[i]);
}
targetArray[2]=nullValue3;
// I tried to add all odd numbers in sourceArray together and assign it to targetArray[2]
for (int i=0; i<sourceArray.length; i++)
{
nullValue4 += getResult(sourceArray[i]);
}
targetArray[3]=nullValue4;
// Same as previous except I need to do that with even numbers.
}
public static int getResult (int x)
{
if (x%2 == 0)
{
return x;
}
else
{
return 0;
}
}
}
You can read my comments above. I realize I can create another method for the last part but I am supposed to use only one method to return odds and evens. I tried almost anything. I can't think of any other ways anymore. Obviously I can't return x in both cases(Yeah I was too desperate to try that).
Straight to the point. I need one method to return x if it's odd or if it's even(We can say it's impossible by the look of that sentence already). I guess that's impossible to do with only one method. I'm not good at java yet so I'm not sure. Maybe there are other ways to do that with only one method which may be so easy. I worked on it for like 6 hours so I'm asking you guys. Thanks.
Create a method to return a boolean if the number is even like so
public static boolean isEven(int x)
{
return (x%2 == 0)
}
Then in your loop for evens
for (int i=0; i<sourceArray.length; i++)
{
if(isEven(x))
nullValue3 += sourceArray[i];
}
For odds just change to if(!isEven(x))
But this is probably deviating from the requirements as you probably want a method that returns an int and you could just put the condition directly in the loop and not need a method
If I understand your question correctly, what you want is to be able to tell the getResult function whether to give you only odd numbers or only even numbers. Without getting complicated, this is what I would do:
public static int getResult(int x, boolean evens) {
if (x % 2 == 0) {
return evens ? x : 0; // shorthand for: if(evens) {return x;} else {return 0;}
} else {
return evens ? 0 : x;
}
}
Simply speaking, I pass a flag value (evens) to the getResult function. This flag tells me whether to filter for even numbers or for odd numbers.
I test whether x is even (x % 2 == 0). If it is, I return it if I'm looking for evens, and I return 0 if I'm looking for odds. If x wasn't even, then I do the opposite.
It would be a little cleaner to write a pair of helper functions, which you could then call from your getResult function.
private static int getIfEven(x) {
if (x % 2 == 0) {
return x;
}
return 0;
}
private static int getIfOdd(x) {
if (x % 2 == 0) {
return 0;
}
return x;
}
public static int getResult(int x, boolean evens) {
// shorthand for:
// if (evens) {
// return getIfEven(x);
// } else {
// return getIfOdd(x);
// }
return evens ? getIfEven(x) : getIfOdd(x);
}
Depending on how much you're allowed to deviate from the current setup (I assume this is homework), you could also just write an isEven(int x) function and call that at each step through the loop, only adding the number if it is/isn't even.