This program is supposed to print all the prime numbers up to an int that you enter, for example:
Enter a Number:
20
2
3
5
7
11
13
17
19
I just cannot get my program to work, I really don't know what to do, so if someone could review it and try to fix it, that would be greatly appreciated, thanks.
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
PrimeGenerator matt = new PrimeGenerator();
System.out.println(matt.nextPrime(number));
}
private int number;
public PrimeGenerator(int n) {
number = n;
}
public int nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i;
}
}
}
}
You're already there actually. You've just got a mistake in the program-flow.
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i; //<-- this return will terminate nextPrim
}
}
Things to fix/improve:
nextPrim would need to return a value within every possible program-branch. This means: consider the case where nextPrim doesn't find any number in the given range and steps out of the loop. Now the program would be stuck without any return-value.
Instead of returning the first prim-number found, you could print that found prim-number and keep the generator running. Nice, easy and solves the hassle with returning anything, since you now can simply declare nextPrim as void. I'd recommend renaming it to printPrims or something like that to make this change clear.
Passing number: You can save a bit of effort by only passing number once to the prim-generator. The simplest solution would be to pass it to nextPrim/printPrims. Now you can remove the instance-variable number and the constructor, which solves the issue with th e signature of the constructor.
1 is not a prim-number to be pedantic. So let's be pedantic and start the outer loop in printPrims with 2, so that 2 will be the first number that is checked for being a prim.
So let's put this into code:
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
PrimeGenerator matt = new PrimeGenerator();
matt.printPrims(number);
}
public void printPrime(int number) {
for (int i = 2; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
A few general hints:
Work through compiler errors. They tell you precisely where and what errors occur within your code.
Think about the flow of your program before even implementing it.
Break the task down into smaller tasks and implement these one after another. As an example: for this problem first print out all numbers in the range 2, number. Afterwards go a step further and add functionality to filter out prim-numbers. Now you've got two components that you can easily test independent of each other.
You were nearly there but your nextPrimes function was terminating prematurely when you returned i, try something like this:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner k = new Scanner(System.in);
System.out.print("Enter an integer:");
int number = k.nextInt();
printPrimesUptoN(number);
}
public static void printPrimesUptoN(int n){
for(int i=2;i<n;i++){
boolean isPrime = true;
for(int j=2;j<i;j++){
if(i % j == 0){
isPrime = false;
break;
}
}
if(isPrime)
System.out.println(i);
}
}
}
Try it here!
There's a few issues with your code, maybe we can fix it together. First things first, you're missing a return statement in nextPrime and there's no empty default constructor PrimeGenerator() because you created a single-arg constructor. Try this:
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
// you probably want to pass your maximum value to the constructor
PrimeGenerator matt = new PrimeGenerator(number);
// without a loop of some sort this will only print a single prime number, e.g.
// Enter a Number:
// 20
// 2
System.out.println(matt.nextPrime(number));
}
private int number;
public PrimeGenerator(int n) {
this.number = n;
}
// you're using the argument as upper boundary for your prime detection while not increasing your lower boundary
// also you're checking if i is a prime here which you always start at 1. this should always return the same value because once you find a prime number you return
// you should consider using an algorithm like Sieve of Eratosthenes (or advanced verions thereof) to determine if a given number is prime
public int nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i;
}
}
// you need to return something at the end of this method or throw an exception
throw new IllegalStateException("no more prime numbers available!");
}
}
This is not a solution which will yield the results you're expecting but it will compile at least. From that point you can move forward and fix the algorithmic issues.
Your original error was in.
PrimeGenerator matt = new PrimeGenerator();
Error:
PrimeGenerator.java:7: error: constructor PrimeGenerator in class PrimeGenerator cannot be applied to given types;
PrimeGenerator matt = new PrimeGenerator();
^
required: int
found: no arguments
reason: actual and formal argument lists differ in length
1 error
Notice that you had a method with the same name as you class, but I don't think you were using it as a constructor and if you were it took an int which you didn't give it. Your method on line 13 was:
public PrimeGenerator(int n) {
number = n;
}
Try doing
new PrimeGenerator().nextPrime(number);
Instead
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
new PrimeGenerator().nextPrime(number);
}
public void nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
}
Optionally, to use your original constructor, you could separate this out.
import java.util.Scanner;
public class PrimeGenerator {
private int number;
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
// Initialize with a number.
PrimeGenerator pg = new PrimeGenerator(number);
pg.printPrimes();
}
// This is the constructer you were misusing.
public PrimeGenerator(int n) {
number = n;
}
public void printPrimes() {
// Actually use your private number variable.
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
}
There are several issues:
Are you using an IDE? If so, which is it, else Why not?. If you consider yourself a beginner, be advised to used one, like Eclipse IDE or NetBeans IDE.
Regarding to your algorithm, at first glance, there is a compilation and a logic problems.
Compilation problem is when the execution of your class not work. In this case the method nextPrime(int number) MUST return an int. Although you put return clause, the method is not returning any value when prime is false. You could easily spot this problem with an IDE.
Another compilation problem, the sentinel or variable i is INSIDE the for loop, and you are printing it's value OUTSIDE of it. Once again, the IDE would help you with this problem.
Logic problem is, you are returning a value if and only if the flag prime is true, so, when calling the method (supposing is working) you only obtain ONE value when you call System.out.println(matt.nextPrime(number));
The correct implementation would have these considerations:
The method doesn't return, i.e public void nextPrime(number) { ..., which means you don't need print in the main method, just call it.
The method actually prints the numbers.
In this way, you can check if i % j is different of zero, then you don't need to process more dividers, breaking the for loop.
Print it.
That's it.
public static void main(String [] args) {
.
.
.
PrimeGenerator matt = new PrimeGenerator();
matt.nextPrime(number);
}
public void printPrime(int number) {
boolean prime = true;
for (int i = 2; i <= number; i++) {
prime = true;
for (int j = 2; j < i; j++) {
if (i % j != 0) {
prime = false;
break;
}
}
if (prime) {
System.out.println(i);
}
}
}
Related
I have a problem with finding prime numbers in an array of randomly generated integers.
I tried using the 'for' loop to go through every element in my array to check whether it's a prime number or not. Although it prints some ints from the array, they are not prime numbers.
public static void main(String[] args) {
defineTable();
printPrimeNumbers();
}
private static int[] tab;
private static int[] defineTable(){
tab = new int[100];
for (int i = 0; i < tab.length; i++){
tab[i] = randomFill();
}
return tab;
}
private static int randomFill (){
Random rand = new Random();
int randomInt = rand.nextInt();
return randomInt;
}
private static void printPrimeNumbers(){
boolean isPrime = true;
for (int i = 0; i < tab.length; i++){
int num = tab[i];
for (int j = 2; j < num; j++){
if (num % j == 0){
isPrime = false;
break;
}
}
if(isPrime){
System.out.println(num + " jest liczbą pierwszą.");
}
}
}
Any solutions to this problem? I started learning Java 4 days ago on my own. So far everything goes well, I understand most of the basics. But this problem seems too complex for me, a beginner.
Edit: I translated most of the code's variables to English from Polish, as my native language is Polish, hope it's understandable.
You're only setting isPrime to true at the beginning of printPrimeNumbers. Once it finds the first composite number, it becomes false, and you never reset it to true again to test the next number.
when writing Java code, try to split the task into functions(should serve a single purpose only). For your code extract the logic of determining Prime into a separate method and pass the random number to check whether it's prime or not, if yes then print otherwise don't print or do nothing.
Please check the below code snippet
A simpler and efficient way to find the prime number
public static 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;
}
private static void printPrimeNumbers(){
for (int i = 0; i < tab.length; i++){
if(isPrime(tab[i])){
System.out.println(tab[i] + " jest liczbą pierwszą.");
}
}
In order to solve a question I have to generate a list of prime numbers from 1 to 3000000, so I tried several ways to do this and unfortunately all failed...
First try: because all prime numbers bigger than 2 are odd numbers, so I first generate a list of odd numbers started with 3 called allOddNums. And then I generate a list of all composite numbers called allComposite. Then I remove all the number in allComposite from allOddNums to obtain prime numbers. Here is my code:
/** Prime Numbers Generation
* Tony
*/
import java.util.*;
public class PrimeNumG {
public static void main(String[] args) {
List <Long> allOddNums = new ArrayList<Long>();
for (long i = 3; i < 200; i += 2) {
allOddNums.add(i);
}
// composite number generator:
List <Long> allComposite = new ArrayList<Long>();
for (long a = 2; a < Math.round(Math.sqrt(3000000)); a += 2) {
for (long b = 2; b < Math.round(Math.sqrt(3000000)); b += 2) {
allComposite.add(a*b);
}
}
// remove duplicated:
Set <Long> hs = new HashSet<Long>();
hs.addAll(allComposite);
allComposite.clear();
allComposite.addAll(hs);
// remove all composite from allRealNums = allPrime
allOddNums.removeAll(allComposite);
allOddNums.add(0, (long)2);
System.out.printf("%s ", allOddNums);
Scanner sc = new Scanner(System.in);
int times = sc.nextInt();
for (int i = 0; i < times; i++) {
int index = sc.nextInt();
System.out.print(allOddNums.get(index) + " ");
}
}
}
In this case, when I need to generate a few prime numbers it works fine. However, if I want to generate until 3000000 it fails me(used up memory).
Second try: I searched online and find an algorithm called sieve of Eratosthenes. then I first generate 2, 3, 5, 7, 9...(all odd numbers + 2), then I remove every 3rd number after 3 and every 5th number after 5. The code is as below:
/** Prime Number Generator
* Tony
*/
import java.util.*;
public class Solution61 {
public static void main(String[] args) {
List<Long> l1 = new ArrayList<Long> ();
// l1 generator: 3 5 7 9 11 ...
for (long d = 3; d < 100; d += 2) {
l1.add(d);
}
l1.add(1, (long)2); // 2 3 5 ...
removeThird(l1); // rm 3rd after 3
removeFifth(l1); // rm 5th after 5, now the l1 will be prime number
Scanner sc = new Scanner(System.in);
int times = sc.nextInt();
for (int i = 0; i < times; i++) {
int index = sc.nextInt();
System.out.print(l1.get(index) + " ");
}
}
/** removeThird : remove every 3rd number after 3
* param List | return void
*/
private static void removeThird(List<Long> l) {
int i = 1;
int count = 0;
while (true) {
if (count == 3) {
l.remove(i);
count = 1;
}
i ++;
count ++;
if (i > l.size()) {
break;
}
}
}
/** removeThird : remove every 5th number after 5
* param List | return void
*/
private static void removeFifth(List<Long> l) {
int i = 2;
int count = 0;
while (true) {
if (count == 5) {
l.remove(i);
count = 1;
}
i ++;
count ++;
if (i > l.size()) {
break;
}
}
}
}
This is still not up to the task because it also runs out of memory.
3rd try:
I tried to generate from 1 to the 3000000, and then remove every number is the product of prime number and another number. The code is as below:
/** print all the prime numbers less than N
* Tony
*/
public class primeGenerator {
public static void main(String[] args) {
int n = 3000000;
boolean[] isPrime = new boolean[n];
isPrime[0] = false; // because 1 is not a prime number
for (int i = 1; i < n; i++) {
isPrime[i] = true;
} // we set 2,3,4,5,6...to true
// the real number is always (the index of boolean + 1)
for (int i = 2; i <= n; i++) {
if (isPrime[i-1]) {
System.out.println(i);
for (int j = i * i; j < n; j += i /* because j is determined by i, so the third parameter doesn't mater*/) {
isPrime[j-1] = false;
}
}
}
}
}
it still fails me, well guess 3000000 is really a big number huh? Is there any simple and brilliant rookie-friendly way to generate prime numbers below 3000000? Thx!
fourth try:
#jsheeran Is this code below what your answer means? when I hit 1093 it gets slower and slower and my IDE still crashed. Plz tell me if I misinterprete your approach, thx!
/** new approach to find prime numbers
* Tony
*/
import java.util.*;
public class PrimeG {
/** isPrime
* To determine whether a number is prime by dividing the candidate number by each prime in that list
*/
static List<Long> primes = new ArrayList<Long> ();
private static void isPrime(long n) {
boolean condition = true;
for (int i = 0; i < primes.size(); i++) {
if (n % primes.get(i) == 0) {
condition = condition && false;
}
}
if (condition) {
findNextPrime(n);
}
}
/** findNextPrime
* expand the list of prime numbers
*/
private static void findNextPrime(long n) {
primes.add(n);
}
public static void main(String[] args) {
primes.add((long)2);
primes.add((long)3);
primes.add((long)5);
primes.add((long)7);
for (int i = 8; i < 3000000; i++) {
isPrime(i);
System.out.printf("%s", primes);
}
}
}
Fixed implementation of Sieve of Eratosthenes (your third try). I believe it should satisfy your needs.
public static void main (String[] args) throws java.lang.Exception {
int n = 3000000;
boolean[] isPrime = new boolean[n+1];
for (int i = 2; i <= n; i++) {
isPrime[i] = true;
}
for (int factor = 2; factor*factor <= n; factor++) {
if (isPrime[factor]) {
for (int j = factor; factor*j <= n; j++) {
isPrime[factor*j] = false;
}
}
}
for (int i = 2; i <= n; i++) {
if (isPrime[i]) System.out.println(i);
}
}
An alternative approach would be to begin with a list of primes consisting of 2 and 3. Have a method isPrime(int) to determine whether a number is prime by dividing the candidate number by each prime in that list. Define another method, findNextPrime(), which isPrime() can call to expand the list as needed. This approach has far lower overhead than maintaining lists of all odd and composite numbers.
Memory is not an issue in your case. Array of size n = 3000000 can be defined inside the stack frame of a function. Actually array of size 10^8 can be defined safely inside a function. If you need more than that define it as a gloabal variable(Instance variable). Coming to your code there is an IndexOutOfBoundsException in your third code. You need to check for factors of a number only uptill sqrt(n). Factors exist in pairs one factor <=sqrt(n) and other >=sqrt(n). So you can optimize the sieve of Eratosthenes algorithm. Here is a link to one wonderful tutorial on various optimizations of sieve.
This can generate prime numbers up to Integer.MAX_VALUE in few milliseconds. It also doesn't take as much memory as in Sieve of Eratosthenes approach.
public class Prime {
public static IntStream generate(int limit) {
return IntStream.range(2, Integer.MAX_VALUE).filter(Prime::isPrime).limit(limit);
}
private static boolean isPrime(int n) {
return IntStream.rangeClosed(2, (int) Math.sqrt(n)).noneMatch(i -> n % i == 0);
}
}
I have written a code for the fourth question of Euler Project.
The question is:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
Here is my code:
public class LargestPalindromeProduct {
private static int product;//integer palindrome number
private static String palindrome;//string palindrome
private static int largestPalindrome(){
for(int i = 100; i<=999; i++){
for(int k = 100; k<=999; k++){
product = i*k;
palindrome = Integer.toString(product);
for(int j = 0; j<= palindrome.length()-1; j++){
if(palindrome.charAt(j) == palindrome.length() - 1 - j){
return product;
}
}
}
}
return product;
}
public static void main(String[] args) {
int largestPalindrome = largestPalindrome();
System.out.println(largestPalindrome);
}
}
This code gives 998001 as the output.
Can you help me to find where the problem is?
You are returning the moment you get 1 match instead of continuing checking until ALL match.
if(palindrome.charAt(j) == palindrome.length() - 1 - j){
return product;
}
As #soong has pointed out the actual comparison is doing charAt() vs length
Better check how you are doing your comparisons.
Close, but for your pattern to work, you must try all combinations and return the largest one. Also, don't short circuit the method on a mis-match, just break out of the loop.
Try a couple changes similar to what i've added...
public class LargestPalindromeProduct {
private static int largestPalindrome() {
int max = 0;
for(int i = 100; i<=999; i++) {
for(int k = 100; k<=999; k++) {
int product = i*k;
if (product <= max) {
continue;
}
String palindrome = Integer.toString(product);
boolean good = true;
for(int j = 0; j<= palindrome.length()-1; j++) {
if(palindrome.charAt(j) != palindrome.charAt(palindrome.length() - 1 - j)) {
good = false;
break;
}
}
if (good)
max = product;
}
}
}
return max;
}
public static void main(String[] args) {
int largestPalindrome = largestPalindrome();
System.out.println(largestPalindrome);
}
What I did was start at 999999 and count downward, then test if the number was a palindrome, and if the number was a palindrome, test if it had 2 integer factors.
I'm not going to give you all the code, but here's one way to check for a palindrome that you might not have thought of.
public static boolean isPalindrome(int palindrome) {
StringBuilder builder = new StringBuilder(Integer.toString(palindrome));
builder.reverse();
return Integer.valueOf(builder.toString()) == palindrome;
}
I'm trying to write a program that displays all prime numbers below the one entered by the user. The only requirement is that it must be multi threaded. This is my first time using Java and multiple threads. Can you help? It compiles, but the output is strange. Maybe it's an address?
import java.util.Scanner;
import java.util.Arrays;
public class prime {
public static void main(String[] args){
// get number from user
System.out.println("Enter a number: ");
Scanner keyboard = new Scanner(System.in);
int num = keyboard.nextInt();
RunPrime runprime1 = new RunPrime (num);
runprime1.start();
Thread.yield();
runprime1.SmallerPrimeNumbers();
}
}
class RunPrime extends Thread {
private int given_number;
RunPrime (int n) {
given_number = n;
}
public void SmallerPrimeNumbers() {
int count = 0;
for (int i = 0; i <= given_number; i++) {
if (CheckPrime(i)) {
count++;
}
}
for (int i = 0; i < count; i++) {
for (int j = 2; j <= given_number; j++) {
if (CheckPrime(j)) {
number[i] = j;
}
}
}
System.out.println(number);
}
public static boolean CheckPrime (int n) {
for (int i=2 ; i<n ; i++) {
if (n%i == 0)
return false;
}
return true;
}
}
Your SmallerPrimeNumbers() function has a second for-loop that doesn't look necessary. You're also assigning and printing the variable number that wasn't declared anywhere (this is probably what's causing you trouble). Since you're only printing them and not saving them, you can simplify the function like this:
public void SmallerPrimeNumbers() {
int count = 0;
for (int i = 0; i <= given_number; i++) {
if (CheckPrime(i)) {
System.out.println(i);
}
}
}
I am trying to print the entire fibonacci sequence up to a given place. So the user would decide how many numbers of the fibonacci sequence they want to see (up to 16 repetitions) and it would print the entire sequence.
My current code only prints the number in the sequences for the place that you choose.
ex: 4 prints 2 instead of 0 1 1 2.
public int Fibonacci(int number){
if(number == 1 || number == 2){
return 1;
}
int fib1=1, fib2=1, fibonacci=1;
for(int count= 3; count<= number; count++){
fibonacci = fib1 + fib2;
fib1 = fib2;
fib2 = fibonacci;
}
return fibonacci;
}
Here is my main method:
import java.util.Scanner;
public class FibonacciPrinter
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter an integer: ");
int input = in.nextInt();
FibonacciGenerator newNumber = new FibonacciGenerator();
for(int fibCount = 0; fibCount < input; fibCount++)
{
System.out.println(newNumber.Fibonacci(input));
}
}
}
I think here,
for(int fibCount = 0; fibCount < input; fibCount++)
{
System.out.println(newNumber.Fibonacci(input));
}
You almost certainly wanted,
for(int fibCount = 0; fibCount < input; fibCount++)
{
System.out.println(newNumber.Fibonacci(fibCount)); // <-- fibCount not input
}
You need to update your method to handle the zero case, for example
public int Fibonacci(int number) {
if (number == 0) return 0;
// ...
}
and in Java, the convention would name Fibonacci to fibonacci because method names are camel case starting with a lower case letter (classes start with a capital letter by convention).