Need help figuring it out errors with my code - java

so I need help figuring it out why my code is not including the number 2 and it is including number 99 on the prime printed line. Do I need to change something on my findPrime()? I tried playing with the index and just got worse.
class Sieve {
private int max;
private boolean[] numbers;
public Sieve(int max) {
if (max < 2) {
throw new IllegalArgumentException();
}
this.max = max;
numbers = new boolean[max];
numbers[0] = false;
numbers[1] = false;
numbers[2] = true;
for (int i = 2; i < max-1; i++) {
numbers[i] = true;
}
}
public void findPrimes() {
for (int num = 2; num < max-1; num++) {
int multiples = num + num;
while (multiples < max-1) {
numbers[multiples-1] = false;
multiples += num;
}
}
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (int num = 2; num < max; num++) {
if (numbers[num]) {
builder.append(num+1).append(" ");
}
}
return builder.toString();
}
}
class Driver
{
// MAIN. Find some primes.
public static void main(String [] args)
{
Sieve sieve = null; // We must initialize SIEVE or Java will cry.
// 5 points. This must print "Sieve size must be at least 2." but without the
// quotes.
try
{
sieve = new Sieve(0);
}
catch (IllegalArgumentException oops)
{
System.out.println("Sieve size must be at least 2.");
}
// 5 points. This must print nothing.
try
{
sieve = new Sieve(100);
}
catch (IllegalArgumentException oops)
{
System.out.println("Sieve size must be at least 2.");
}
// 10 points. This must print integers from 2 to 99, separated by blanks.
System.out.println(sieve);
// 10 points. This must print the prime numbers between 2 and 99, separated by
// blanks. They are:
//
// 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
sieve.findPrimes();
System.out.println(sieve);
}
}
It is displaying this, instead of having the number 2 at the beginning and not having the number 99 at the last line of the program.
Sieve size must be at least 2.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 99

Your toString() method starts looping at num = 2 (which appends num+1 to the output). Your loop should start at 1.
public String toString() {
StringBuilder builder = new StringBuilder();
for (int num = 1; num < max; num++) { . // used to start at 2
if (numbers[num]) {
builder.append(num+1).append(" ");
}
}
return builder.toString();
}
}
Plus your code sets numbers[1] = false. That should be numbers[1] = true.
You are also looping until < max - 1. Consider looping until < max.

I made a few changes to your code the big things to point out is that you don't need max. Your findPrimes() looks ok but is difficult to read and hard to verify for correctness. Your toString() method should be iterating over every element and if that element is true append it to the list.
also 1 is not prime so numbers[1] = false; is as it should be. Why is 1 not a prime number?
class Sieve {
// private int max; // max is superfluous use numbers.length instead
private boolean[] numbers;
public Sieve(int max) {
if (max < 2) {
throw new IllegalArgumentException();
}
numbers = new boolean[max];
numbers[0] = false;
numbers[1] = false;
numbers[2] = true;
for (int i = 2; i <numbers.length; i++) {
numbers[i] = true;
}
}
public void findPrimes() {
// a bit more compact and neater in my opinion
for (int num=2; num<numbers.length; num++) {
for (int multiple=num+num; multiple<numbers.length; multiple+=num) {
numbers[multiple] = false;
}
}
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
// you should be iterating from 0 to 99
for (int i=0; i<numbers.length; i++) {
if (numbers[i]) {
builder.append(i).append(" ");
}
}
return builder.toString();
}
}
class Driver
{
// MAIN. Find some primes.
public static void main(String [] args)
{
Sieve sieve = null; // We must initialize SIEVE or Java will cry.
// 5 points. This must print "Sieve size must be at least 2." but without the
// quotes.
try
{
sieve = new Sieve(0);
}
catch (IllegalArgumentException oops)
{
System.out.println("Sieve size must be at least 2.");
}
// 5 points. This must print nothing.
try
{
sieve = new Sieve(100);
}
catch (IllegalArgumentException oops)
{
System.out.println("Sieve size must be at least 2.");
}
// 10 points. This must print integers from 2 to 99, separated by blanks.
System.out.println(sieve);
// 10 points. This must print the prime numbers between 2 and 99, separated by
// blanks. They are:
//
// 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
sieve.findPrimes();
System.out.println(sieve);
}
}

Related

How can I print the prime numbers ending with 1 in a given range and the nearest one after b?

Sample input :
10
100
Sample output :
11,31,41,61,71,101
from the above code I can get the sample output value upto the value 71,how can I get nearest prime number ending with 1 after b.
Here is the code I tried:
import java.util.*;
public class Program{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
int a=in.nextInt();
int b=in.nextInt();
int i,j,count;
for(i=a;i<=b;i++)
{
for(j=2;j<=b;j++)
{
if(i%j==0)
break;
}
if(j==i && j%10==1)
{
System.out.println(i);
}
}
}
You do not need to divide a number by numbers up to it in order to check if it is prime. You just need to check up to its square root. Check https://en.wikipedia.org/wiki/Primality_test. Do it as follows:
Using a for loop
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter two integers separated by space: ");
int a = in.nextInt();
int b = in.nextInt();
int i, j, sqrt;
// Note that there are three sections in the declaration of a 'for' loop:
// for(initialization;condition;change) where none of the sections is
// mandatory. There is no condition put in the loop syntax given below. The
// condition for termination has been put after printing the prime number.
for (i = a;; i++) {
sqrt = (int) Math.sqrt(i);
for (j = 2; j <= sqrt; j++) {
if (i % j == 0) {
break;
}
}
// If the loop with j completed without a break, the number is prime. Note that
// 1 is not a prime number.Also, the last digit of the number should be 1.
if (j > sqrt && Math.abs(i) != 1 && i % 10 == 1) {
System.out.print(i + " "); // Print the prime
if (i >= b) {// Condition for termination
break;
}
}
}
}
}
Alternatively, using a while loop
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter two integers separated by space: ");
int a = in.nextInt();
int b = in.nextInt();
int i = a, j, sqrt;
while (true) {
sqrt = (int) Math.sqrt(i);
for (j = 2; j <= sqrt; j++) {
if (i % j == 0) {
break;
}
}
// If the loop with j completed without a break, the number is prime. Note that
// 1 is not a prime number.Also, the last digit of the number should be 1.
if (j > sqrt && Math.abs(i) != 1 && i % 10 == 1) {
System.out.print(i + " "); // Print the prime
if (i >= b) {// Condition for termination
break;
}
}
i++;
}
}
}
A sample run:
Enter two integers separated by space: 10 100
11 31 41 61 71 101
Another sample run:
Enter two integers separated by space: 10 200
11 31 41 61 71 101 131 151 181 191 211
Add condition in both the for loops like I<= b*2;
After that before printing the series add one more if block or add the condition in if(j==1 && j%10==1)
Condition-
You should have to check what is value of i and whether it's greater than b or not. If it's greater than b then it should be end with 1 and nearer value otherwise no need to print and break it as other values you don't need at all.
I'm assuming you need a prime satisfying these conditions:
within a range (lower to upper)
ending in 1
nearest to a query value
If so, wouldn't the best strategy be to search outwards in both directions (below and above) and stop when you first hit a prime ending in 1?
public static int nearest1Prime(final int lower, final int upper, final int val)
{
if(val < lower || val > upper) return 0;
int before, after;
if((val % 10) == 1)
{
if(isPrime(val))
return val;
before = val - 10;
after = val + 10;
}
else
{
int base = 10 * (val / 10);
if(val == base)
{
after = base+1;
before = after-10;
}
else
{
before = base+1;
after = before+10;
}
}
int prime = 0;
while(prime == 0 && (before >= lower || after <= upper))
{
if(before >= lower && isPrime(before))
prime = before;
if(after <= upper && isPrime(after) && (prime == 0 || (after-val) < (val-before)))
prime = after;
before -= 10;
after -= 10;
}
return prime;
}
public static boolean isPrime(int v)
{
for(int i=(int)Math.sqrt(v); i>1; i--)
{
if((v % i) == 0) return false;
}
return true;
}
Testing:
int lower = 10;
int upper = 100;
for(int i=lower; i<=upper; i++)
{
int prime = nearest1Prime(lower, upper, i);
System.out.println("Nearest Prime: " + i + " : " + prime);
}
Output:
10 : 11
11 : 11
12 : 11
13 : 11
14 : 11
15 : 11
16 : 11
17 : 11
18 : 11
19 : 11
20 : 11
21 : 11
22 : 31
23 : 31
24 : 31
25 : 31
26 : 31
27 : 31
28 : 31
29 : 31
30 : 31
31 : 31
32 : 31
33 : 31
34 : 31
35 : 31
36 : 31
37 : 41
38 : 41
39 : 41
40 : 41
41 : 41
42 : 41
43 : 41
44 : 41
45 : 41
46 : 41
47 : 41
48 : 41
49 : 41
50 : 41
51 : 41
52 : 61
53 : 61
54 : 61
55 : 61
56 : 61
57 : 61
58 : 61
59 : 61
60 : 61
61 : 61
62 : 61
63 : 61
64 : 61
65 : 61
66 : 61
67 : 71
68 : 71
69 : 71
70 : 71
71 : 71
72 : 71
73 : 71
74 : 71
75 : 71
76 : 71
77 : 71
78 : 71
79 : 71
80 : 71
81 : 71
82 : 71
83 : 71
84 : 71
85 : 71
86 : 71
87 : 71
88 : 71
89 : 71
90 : 71
91 : 71
92 : 71
93 : 71
94 : 71
95 : 71
96 : 71
97 : 71
98 : 71
99 : 71
100 : 71
Here's how you can do it, run the first loop indefinitely and break it when i is greater than b and it's a prime with 1 at the end.
This is the implementation just modifying your code a bit-
import java.util.*;
class Program{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
int a=in.nextInt();
int b=in.nextInt();
boolean flag = false;
int i,j,count;
for(i=a;;i++) {
if(i>b) flag = true;
for(j=2;j<=i;j++) {
if(i%j==0)
break;
}
if(j==i && j%10==1) {
System.out.println(i);
if(flag) break;
}
}
}
}
Try this with a few improvements.
first check to see if divisible by 2
then, since 2 is taken care of, divide only by odd numbers
starting with 3, not exceeding the sqrt of the number under test.
then just continue until the search parameter are met.
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
outer:
for (int i = a; i <= Integer.MAX_VALUE; i++) {
// first check division by 2 so you can increment by 2 later
if (i % 2 == 0) {
continue;
}
// increment from 3 to square root of i by 2's
for (int j = 3; j <= Math.sqrt(i); j+=2) {
if (i % j == 0) {
// not prime so continue with outer loop
continue outer;
}
}
if (i % 10 == 1) {
System.out.print(i + " ");
// keep searching until i > b.
if (i > b) {
break;
}
}
}
for input of 10 100 Prints
11 31 41 61 71 101

Top Down Recursive method isn't working and not sure how to fix it. Java

I have a homework problem for my "Data Structure and Algorithm class" - Implement a Top Down Recursive Merge Sort in Java. Demonstrate that your sort works by generating a random sequence of 100 numbers, printing them in their raw unsorted form, sorting them, and then printing them out in their sorted order.
And i did a little bit of coding and it seems to be right but i am getting an error and can't figure out what i did wrong.
class RecursiveMergeSort
{
void TopDownMergeSort(int[] mainArray, int[] copyArray) // mainArray, copyArray, int n
{
CopyArray(mainArray, copyArray);
Split(copyArray, 0, 100, mainArray);
}
private void Split(int[] copyArray, int start, int end, int[] mainArray)
{
if(end - start < 2)
{
return;
}
int middle = (end + start) / 2;
Split(mainArray, start, middle, copyArray);
Split(mainArray, start, end, copyArray);
CombineArray(copyArray, start, middle, end, mainArray);
}
private void CombineArray(int[] mainArray, int start, int middle, int end, int[] copyArray)
{
int s = start; //a
int m = middle; //b
for (int i = start; i < end; i++)
{
if(s < middle && (m >= end || mainArray[s] <= mainArray[m]))
{
copyArray[i] = mainArray[s];
s = s + 1;
}
else
{
copyArray[i] = mainArray [m];
m = m + 1;
}
}
}
private void CopyArray(int[] mainArray, int[] copyArray)
{
System.arraycopy(mainArray, 0, copyArray, 0, 100);
}
void UnsortedArray(int[] unsortedArray)
{
for(int i = 0; i < unsortedArray.length; i++)
{
int random = (int)Math.floor(Math.random() * 100) + 1;
unsortedArray[i] = random;
System.out.println("\t" + i + unsortedArray[i]);
}
}
void SortedArray(int[] unsortedArray)
{
for(int i = 0; i < unsortedArray.length; i++)
{
System.out.println("\t: " + i + unsortedArray[i]);
}
}
}
And here is Driver:
public class RecursiveDriver
{
public static void main(String[] args)
{
int[] randomNumbers = new int[100];
int[] sorted = new int[100];
RecursiveMergeSort test = new RecursiveMergeSort();
System.out.println("Unsorted Array:");
test.UnsortedArray(randomNumbers);
System.out.println("Sorted Array");
test.TopDownMergeSort(randomNumbers, sorted);
test.SortedArray(randomNumbers);
}
}
This is what I am expecting:
Unsorted List: 100 61 8 76 51 89 30 63 11 1 47 74 85 63 80 45 18 34 74 25 8 90 61 44 25 2 40 100 47 1 72 24 86 80 87 75 46 85 14 30 43 31 27 48 96 96 26 20 44 1 67 1 30 35 87 78 18 46 37 31 6 61 62 92 71 45 6 10 12 38 96 14 22 83 96 31 65 74 58 47 87 65 28 61 91 73 3 92 87 22 68 0 9 18 13 89 36 8 35 44
Sorted List: 0 1 1 1 1 2 3 6 6 8 8 8 9 10 11 12 13 14 14 18 18 18 20 22 22 24 25 25 26 27 28 30 30 30 31 31 31 34 35 35 36 37 38 40 43 44 44 44 45 45 46 46 47 47 47 48 51 58 61 61 61 61 62 63 63 65 65 67 68 71 72 73 74 74 74 75 76 78 80 80 83 85 85 86 87
And that’s the outcome I get when I run my script:
But i am getting:
Unsorted Array:
035
175
270
392
436
And it keeps going until I get an error:
Sorted Array Exception in thread "main" java.lang.StackOverflowError at RecursiveMergeSort.Split(RecursiveMergeSort.java:16) at RecursiveMergeSort.Split(RecursiveMergeSort.java:17)
It seems like it has something to do with line 16/17 but i am not completely sure how to fix it. Thanks for all the help.
int middle = (end + start) / 2;
Split(mainArray, start, middle, copyArray);
Split(mainArray, start, end, copyArray);
CombineArray(copyArray, start, middle, end, mainArray);
Should be
int middle = (end + start) / 2;
Split(mainArray, start, middle, copyArray);
Split(mainArray, middle, end, copyArray);
CombineArray(copyArray, start, middle, end, mainArray);
You were super close, just the start index of the second recursive call should be from the middle index to the end, not the start all the way to the end again (resulting in the stack overflow error)
On a side note - you should rename your methods to comply with the standard, ex: they start with a lower-case letter such as:
private void combineArray(int[] mainArray, int start, int middle, int end, int[] copyArray)

Two dimensional array with different row length. I need to drop min, max and calculate the average for each line in Java

public class Average {
static int[][] myDouble = new int[10][12];
static int x = 0, y = 0;
static int strDouble;
public Average() {
try {
BufferedReader in = new BufferedReader(new FileReader("StudentIdAverage.txt"));
String line;
while ((line = in.readLine()) != null) {
String[] values = line.split("\\s+");
for (String str : values) {
strDouble = Integer.parseInt(str);
myDouble[x][y] = strDouble;
y = y + 1;
}
x = x + 1;
y = 0;
}
in.close();
} catch (IOException ioException) {
}
}
public static void main(String[] args) {
Average arr = new Average();
//int[][] residuescores = arr.myDouble;
for (int i = 0; i < myDouble.length; ++i) {
int sum = 0;
int average = 0;
for (int j = 0; j < myDouble[i].length; ++j) {
Arrays.sort(myDouble[i]);
sum+=myDouble[i][j];
System.out.print(Average.myDouble[i][j] + " ");
}
average = (sum/myDouble[i].length);
System.out.println(" ");
System.out.println(average);
}
}
}
input File:-
45 72 90 50 67 63 81 71 55 56 80 74/n 55 54 79 72 75 68/n 51 88 79
72/n 98 52 52 53 50 92 67 99 92 50 61 91/n 94 48 53 92 97/n 97 69 77
74 68 54 87 74 54 83 58 69/n 75 49 87 61 66 53 79 48 96 60/n 58 71 51
73 53 75 93 81 45 69 78 65/n 50 88 78 81 99 61 97 70 87 80 69/n 91 89
97 80 93 82 92 49 52 69 96 61
If you are using java 8 you can utilize streams and SummaryStatistics to calculate average/min/max like below
static Integer[][] myDouble = new Integer[10][12];
for (int i = 0; i < myDouble.length; ++i) {
IntSummaryStatistics statistics = Arrays.asList(myDouble[i]).stream().filter(intValue -> intValue!=null).collect(Collectors.summarizingInt(Integer::intValue));
System.out.println("Average: "+statistics.getAverage()+", min: "+statistics.getMin()+", max: "+statistics.getMax());
}
If you can not use java 8 then note that the issue with your code is that you are using primitive int in your array which will initialize the values to 0 and thus you get 0 when the row has less values than 12. One way to solve it is to change your array to Integer class but remember to skip the entries which have null as now instead of 0 you will get null in the rows with less entries.
your code working with int array changed to Integer, skipping nulls and using count instead of array.length:
for (int i = 0; i < myDouble.length; ++i) {
int count = 0; // count the values used to calculate sum
int sum = 0;
int average = 0;
for (int j = 0; j < myDouble[i].length; ++j) {
if(myDouble[i][j] == null) //skip the null values
continue;
//Arrays.sort(myDouble[i]);
sum+=myDouble[i][j];
count++;
System.out.print(App.myDouble[i][j] + " ");
}
average = (sum/count); //use count instead of lenght
System.out.println(" ");
System.out.println(average);
}

format 12 by 12 multiplication table

My program outputs the table like this:
1 2 3 4 5 6 7 8 9 10 11 12
2 4 6 8 10 12 14 16 18 20 22 24
3 6 9 12 15 18 21 24 27 30 33 36
4 8 12 16 20 24 28 32 36 40 44 48
5 10 15 20 25 30 35 40 45 50 55 60
6 12 18 24 30 36 42 48 54 60 66 72
7 14 21 28 35 42 49 56 63 70 77 84
8 16 24 32 40 48 56 64 72 80 88 96
9 18 27 36 45 54 63 72 81 90 99 108
10 20 30 40 50 60 70 80 90 100 110 120
11 22 33 44 55 66 77 88 99 110 121 132
12 24 36 48 60 72 84 96 108 120 132 144
I need to make it look a little better. Need your help.
This is my code:
int a;
int b;
for (a=1; a<=12; ++a)
{
for (b=1; b<=12; ++b)
{
System.out.print(a*b+" ");
}
System.out.println();
}
Use String System.out.printf(""). Like:
System.out.printf("%4d",a*b);
or
System.out.print(String.format("%4d",a*b));
You should use printf in order to format your output.
System.out.printf("%4d", (a*b));
Check the syntax for the format argument here.
Try to give tab space
System.out.print(a * b + "\t");
try
public static void main(String[] args) {
int a;
int b;
int sum;
for (a = 1; a <= 12; ++a) {
for (b = 1; b <= 12; ++b) {
sum = a * b;
System.out.print(sum);
if(sum < 10){
System.out.print(" ");
}else if(sum >= 100){
System.out.print(" ");
}else if(sum >= 10){
System.out.print(" ");
}
}
System.out.println();
}
}
or
public static void main(String[] args) {
int a;
int b;
for (a = 1; a <= 12; ++a) {
for (b = 1; b <= 12; ++b) {
System.out.printf("%4d", (a*b));
}
System.out.println();
}
}
Use:
System.out.print(a*b+"\t");
which uses a escape sequence that will tab each value appropriately.
I sugest to use a table like here
response.getWriter().append("<table><body>");
for (int i = 1; i < width +1 ; i++) {
response.getWriter().append("<tr>");
for (int j = 1; j < height +1; j++) {
response.getWriter().append("<td>").append(String.format("%4d",i*j)).append("</td>");
}
response.getWriter().append("</tr>");
}
response.getWriter().append("</body></table>");
public class JavaApplication21 {
public static void main(String[] args) {
for(int i=1;i<13;i++) {
for(int j=1;j<=12;j++) {
System.out.printf("%d x %d = %d \n",i,j,(i*j));
System.out.println();
}
}
}
}
package rest;
public class doubt {
public static void main (String[] args) {
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
System.out.printf("%4d",i*j);//+i*j+" ");
}
System.out.println("\n");
}
}
}

Java: Is it possible to make line break x times inside for loop?

I tried to Google and search StackOverflow my question but I didn't found any answers to this.
I have made an array where both size and values are randomly generated. When the array values have been printed 20 times I would like to make a line break, but without printing the rest values with always new line.
Here is my code:
public static void catArr() {
Random rändöm = new Random();
int size = rändöm.nextInt(100);
int[] arr = new int[size];
for (int i = 0; i < size; i++) {
arr[i] = rändöm.nextInt(100);
}
Arrays.sort(arr);
for (int i = 0; i < size; i++) {
System.out.print(" " + arr[i]);
if (i > 20)
System.out.println(); //How to do this only once?
else if (i > 40)
System.out.println(); //Same here?
}
}
And this is one of the generated outputs:
3 8 10 25 30 31 34 38 46 50 55 59 62 66 67 68 68 68 72 76 76 81
82
83
84
86
91
92
93
94
94
97
I think that one way to solve this is using 2-D array, but I would like to know if there is another way.
Yay thanks to Patric, I got the wanted result:
0 2 3 7 7 9 11 14 14 16 18 19 24 25 26 28 28 30 30 31
31 33 33 34 41 41 41 42 43 44 45 46 51 51 52 53 59 60 61 62
62 62 63 65 65 67 67 68 69 70 74 74 76 78 82 83 84 84 87 88
89 93 93 94 94 94 95
try using
if ( ( i % 20 ) == 0 ){
System.out.println();
}
if i divided by 20 leaves no remainder then print a new line!
Maybe
if (i % 20==0)
can solve your else if problem.
Use (++i % 20) == 0 and remove i++ from loop; pre-increment avoid first unwanted line break.
Literally, this will do what you seem to want:
if (i == 20)
System.out.println();
else if (i == 40)
System.out.println();
But I have a feeling that you actually want to add a newline after the 20th, 40th, 60th and so on.
if (i % 20 == 0)
System.out.println();
And if you want to output exactly one newline at the end, then you need something like this:
for (int i = 0; i < size; i++) {
if (i > 1 && i % 20 == 1) {
System.out.println();
System.out.print(" " + arr[i]);
}
System.out.println();
You may use boolean for your Sys outs.
boolean myBoolean = true;
if(myBoolean){
//print
myBoolean = false; //set boolean to false.
}
On the other hand, in my preferences, I still stick with my integer flagging.
int isTrue = 1;
if(isTrue == 1){
//print
isTrue = 0;
}

Categories