Can't see where I'm dividing by 0? - java

Here is all the code I think anyone would need to be able to asses my problem
1 import.java.util.Scanner
2 public class ccattano_Sieve{
3 private boolean [] primes = new boolean [50001];
4 private int upper;
5 private int lower;
6
7 public ccattano_Sieve(){
8 upper = 50000;
9 lower = 1;
10 for (int i = 2; i < primes.length; i++){
11 primes[i] = true;
12 }
13 primes[0] = false;
14 primes[1] = false;
15 }
16
17 public void processSieve(){
18 for (int i = 2; i < Math.round(Math.sqrt(50000)); i++){
19 if (primes[i] == true){
20 for (int c = 2; c < (primes.length - 1); i++){
21 if (c % i == 0){
22 primes[c] = false;
23 }
24 else{
25 primes[c] = true;
26 }
27 }
28 }
29 }
30 }
I'm pretty sure my else statement on lines 24 - 26 aren't needed I added it when trying to trouble shoot. But on line 21 when trying to run the code I receive a divide by zero error. The exact error is as follows.
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ccattano_Sieve.processSieve(ccattano_Sieve.java:21)
at ccattano_SieveTest.main(ccattano_SieveTest.java:7)
This line "at ccattano_SieveTest.main(ccattano_SieveTest.java:7)" calls the code I pasted so it can be ignored. So line 21 is the main issue and I can't find a solution.

The modulus operator is the "rest of the division" meaning that it involves a division.
I believe you have a bug on line 20 where you are incrementing i instead of c.
This means the i variable will overflow (reach so high that it will turn negative) and eventually will turn into 0.

You never update the value of c in your inner loop; instead you increase i by the length of your array minus 1 every time up till the square root of 50,000. I'd suspect this is an error and not what you want to do, but I await a comment to the contrary.

Related

Printing pattern from list in Java

What I have done here is taken the contents of the table below and stored them in a list called tableElems
0 1 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
List<WebElement> tableElems = chrome.findElements(By.tagName("td"));
From this table I want to print in a pattern starting at the 4th element (#3 in the table) and I want to print 3 elements, then skip the next 6, print the next 3 and then skip the next 6, etc. etc.
So my expected output would be 3 4 5 12 13 14 21 22 23 30 31 32
My initial attempt ended with
for (int i = 3; i<tableElems.size(); i++) {
if(i % 3 == 0) { System.out.println(tableElems.get(i).getText()); }
else if(i % 4 == 0) { System.out.println(tableElems.get(i).getText()); }
else if(i % 5 == 0) { System.out.println(tableElems.get(i).getText()); }
}
Obviously this is wrong, because my % 3 will print the 9th element, % 4 will print the 16th element, etc.
I am having trouble wrapping my head around this, so any advice to point me in the right direction is appreciated!
try this:
for (int i = 3; i<tableElems.size(); i++) {
if (((i / 3) % 3) == 1) { System.out.println(tableElems.get(i).getText()); }
}
Think about this as dividing into groups of nine, and further dividing each group of 9 into groups of 3. on the second group of 3 (i.e. 3-5, 12-14) it will display.
int offset = 4;
int width = 3;
advice:
for each row in table check offset + width is under the row width, and then start from offset + 0, offset + 1 upto offset + width
and continue this loop for all the row of table
You mentioned that tableElems is a list, so I assume it's akin to a single-dimension array, rather than what appears to be a multi-dimensional table like you've laid out(I assume for visual purposes).
You're right by starting the for loop at i = 3. The easiest way, IMO, to do this is to just bump the loop ahead several spaces in the array after you've printed three elements. Here's my solution using C# and an array; you should be able to convert it to Java pretty easily.
int counter = 0;
for (int i = 3; i < array.Length; i++)
{
if (counter < 3)
{
Console.WriteLine(array[i]);
counter++;
}
else
{
i += 5; // we are incrementing by one on the next pass, so this can be 5
counter = 0;
}
}
If you want to stick to %, then this should work
int rowSize = 9;
for (int i = 0; i < tableElems.size(); i++) {
int column = i % rowSize;
if (column >=3 && column <= 5) {
System.out.println(tableElems.get(i).getText());
}
}
Update: Java code
for (int i = 3; i<tableElems.size(); i += 9) {
System.out.println(tableElems.get(i).getText());
System.out.println(tableElems.get(i+1).getText());
System.out.println(tableElems.get(i+2).getText());
System.out.println(tableElems.get(i+3).getText());
}
If you are creating a larger pattern:
int starting = 3;
int nextStartDistance = 9;
int waveCount = 3;
for (int i = starting; i<tableElems.size(); i += nextStartDistance) {
for (int b = 0; b <= waveCount; b ++) {
System.out.println(tableElems.get(i).getText());
}
}
This code is written in JavaScript, but the algorithm considered:
var list =[
0,1,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];
for (var index = 3; index <= list.length; index +=9 ) {
var a = list[index];
var b = list[index+1];
var c = list[index+2];
var d = list[index+3];
console.log(a,b,c,d);
}
Result will be what you expected:
// 3 4 5 6
// 12 13 14 15
// 21 22 23 24
// 30 31 32 33
// user:~$
for (int i = 3; i < tableElems.size(); i += 9) {
for (int j = i; j < i + 3 && j < tableElems.size(); j++) {
System.out.println(tableElems.get(j).getText());
}
}
i think this would be very close to your code:
for (int i = 3; i < tableElems.size(); i++) {
if (i % 3 == 0) {
System.out.println(tableElems.get(i).getText());
} else if ((i % 3) == 1) {
System.out.println(tableElems.get(i).getText());
} else if ((i % 3) == 2) {
System.out.println(tableElems.get(i).getText());
i = i + 6;
}
}
i just adapted your modulo and skip 6 elements every time i hit the last one to print out
furthermore its quite effective because all unneeded elements are just skipped instead of iterated and checked
Assuming you only care about the values out of your table and the html structure is standard html tags as shown on your questions, then you can use css selector to select appropriate values.
chrome.findElements(By.cssSelector("td:nth-child(4),td:nth-child(5), td:nth-child(6)"))
Please note that css nth-child selector is 1 based.

Checking for Duplicates in an Array Backwards

This is the same person who had trouble with the last array problem just one or two days ago.
We've a new assignment which asks us to find and replace duplicates in an array of randomly generated numbers. I wrote a code and sent it to my teacher for feedback; she responded with this solution:
So, take the first random num and store into the first slot (this can be done before the loop). Then, start a loop that creates the second random num and tests backwards to see if there are duplicates from the ones already stored. So, a backwards loops that tests for duplicates and counts down to 0 from the current location and replaces duplicates. Once that test passes, then you'll go to the next element, create a new random number, and then test the ones before it for duplicates.
I've done this here, and it's reduced the number of randomly generated numbers, but I still run into the stray duplicate:
import java.lang.Object;
import java.util.Random;
public class Prog433a {
public static void main(String[]args) {
Random randslct = new Random();
int[] list = new int[20];
int counter = 0;
int index = 0;
int min2 = 0;
System.out.println("\nAfter");
for (int k = 0; k < list.length - 1; k++) {
list [k] = randslct.nextInt(30) + 1;
for (int z = list.length - 1; z >= 0; z--) {
if (list[k] == list[z] && z!=k) {
while (list[k] == list[z]) {
list [k] = randslct.nextInt(30) + 1;
}
}
}
}
int min = list[0];
while (counter < list.length - 1) {
for (int x = 0; x < list.length - 1; x++) { // scroll through the indexes.
if (list[x] < min) {
min = list[x];
index = x; // keep the index of the biggest number.
}
}
System.out.println(list[index]);
min = 100 * (list[index]);
list[index] = 100 * (list[index]); // change the value in the original array so it won't find the same max again
counter++;
}
}
}
System Output:
After
2
5
6
10
11
12
13
15
16
17
19
22
22
24
25
27
28
29
29
After
1
2
2
4
5
7
8
9
10
13
15
16
21
24
25
26
28
29
30
After
1
2
3
5
6
7
11
12
13
14
15
16
18
21
22
25
26
27
29
After
2
3
3
4
6
10
12
14
15
16
17
20
22
23
24
25
26
27
30
After
7
8
11
12
13
14
15
16
17
17
18
19
20
21
23
24
27
29
30
I posted my output towards the bottom.
Because this is an introductory coding class, I'd prefer if the solution did not involve Sets or any of the like. But alas, beggars cannot be choosers.
Is there something I have forgotten to add?
Your problem is that when you detect a duplicate you generate a new number, but you never go back and check that the the newly generated number is not a duplicate of the numbers you already checked. When you run into a duplicate you'll need to reset the checking loop through some mechanism.
I fixed up the code to work around the problem, but it's not the prettiest solution. I also did some minor optimisation as you were looping through unnecessary indices.
import java.util.Random;
public class Prog433a {
public static void main(String[] args) {
Random randslct = new Random();
int[] list = new int[20];
int counter = 0;
int index = 0;
int min2 = 0;
System.out.println("\nAfter");
for(int k = 0; k < list.length - 1; k++) {
list[k] = randslct.nextInt(30) + 1;
boolean unique = true;
for(int z = k - 1; z >= 0; z--) {
if(list[k] == list[z]) {
if(list[k] == list[z]) {
unique = false;
break;
}
}
}
if(!unique) {
// Repeat last index
--k;
}
}
int min = list[0];
while(counter < list.length - 1) {
for(int x = 0; x < list.length - 1; x++) { // scroll through the indexes.
if(list[x] < min) {
min = list[x];
index = x; // keep the index of the biggest number.
}
}
System.out.println(list[index]);
min = 100 * (list[index]);
list[index] = 100 * (list[index]); // change the value in the original array so it won't find the same max again
counter++;
}
}
}
Your mistake is when you try to add a new number. You just check, if it isn't the same as the one before, but not if it is the same as twice before. You can do this as follow:
boolean isDuplicate(int index, int[] list){
for(int i=index-1; i>=0;i--){
if(int[i]==int[index])
return false
}
return true;
}
instead of your inner of the for-loop you can now write:
do{
list[k] = randslct.nextInt(30) + 1;
}while(isDuplicate(k, list));
Also you should change your output, e.g. give the already written output a negative value and ignore negative values. If you want to change the numbers up to e.g. 200 your code now won't work.
Lets take this by example. Consider that the current list that has been generated is:
list = [5, 7, 9, 3, 8, 9]
where 9 is the current number.
Now in the for-loop, you iterate from list[6] to list[0]. Here, in comparision, you come to 2nd index (list[2]) where the condition
list[k] == list[z] && z != k
turns out to be true and a new random number is generated. Lets assume that here the new random number that you generated is '8'. The loop terminates successfully and your array now has a duplicate.

Why does my factorial program print 0?

This code is meant to find 100 factorial and the sum the digits in the number. However, it returns 0.
Why does this happen?
public class Problem20 {
public static void main(String[] args){
int num = 100;
for(int i = 1; i< 100; i++){
num = num * i;
}
String numstring = Integer.toString(num);
int sum = 0;
for(int j = 0; j < numstring.length(); j++){
sum += numstring.charAt(j) - '0';
}
System.out.print(sum);
}
}
Every time you multiply by 2, you add a 0 to the low bits of binary representation of the number.
According to the JLS ยง15.17.1:
If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values.
Here's some code to demonstrate this point. As you can see, the number of 0 at the end of the number slowly increases; soon as we get to 32, the low order bits become all 0. See: Why does this multiplication integer overflow result in zero?
public class Problem20 {
public static void main(String[] args) {
int num = 100;
for (int i = 1; i < 33; i++) {
num = num * i;
System.out.println(i + "\t" + Integer.toBinaryString(num));
}
}
}
Output:
1 1100100
2 11001000
3 1001011000
4 100101100000
5 10111011100000
6 10001100101000000
7 1111011000011000000
8 1111011000011000000000
9 10001010011011011000000000
10 10101101000010001110000000000
11 11101101111011000011010000000000
12 100111000100100111000000000000
13 11111011111011111011000000000000
14 11000111000110111010000000000000
15 10101010100111100110000000000000
16 10101001111001100000000000000000
17 1001000010001100000000000000000
18 10100111011000000000000000000
19 10001101100001000000000000000000
20 1110010100000000000000000000
21 101100100100000000000000000000
22 11010100011000000000000000000000
23 10100101000000000000000000000
24 11101111000000000000000000000000
25 1010111000000000000000000000000
26 11010110000000000000000000000000
27 10010010000000000000000000000000
28 11111000000000000000000000000000
29 11000000000000000000000000000
30 11010000000000000000000000000000
31 110000000000000000000000000000
32 0
You can solve this problem by using BigInteger instead of int, e.g.
import java.math.BigInteger;
public class Problem20 {
public static void main(String[] args) {
BigInteger num = BigInteger.valueOf(100);
for (int i = 1; i < 100; i++) {
num = num.multiply(BigInteger.valueOf(i));
System.out.println(num);
}
}
}
Alright.
1! = 1
2! = 2
3! = 6
4! = 24
.
.
.
10! = 3628800
.
.
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Do you think this fits in any of those data-types?
What happens once a number crosses the limit? It overflows. And hence you get a wrong answer.
So what do I do?
Use BigInteger.

Missing the 2 and 3 in Prime [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I am missing the prime numbers, 2 and 3 from the output.
public static ArrayList<Integer> findPrimes(int n){
ArrayList<Integer> primes = new ArrayList<Integer>();
for (int i = 2; i < n; i++){
for(int x = i - 1; x > 2; x--)
if(i % x == 0)
break;
else if(x == 3 && i != 4)
primes.add(i);
}
return primes;
}
When I put n = 72, it prints good, but 2 and 3 are not being output. I have no clue why it keeps printing that. Any help would be great. As shown below.
Output:
Prime numbers: 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
Thanks! If you have another way, feel free to throw out, something I can learn from. Thanks a lot!
Your code explains the problem. The second for loop will terminate before it's executed even once due to the conditional always being false for values 3 and below.
First loop run: i = 2, x = 1, 1 is not more than 2, so the loop does not run.
Second run: i = 3, x = 2, 2 is not more than 2, so once again, same priblem.
When i=2 or i=3, x would initialise to 1 or 2, hence it will never enter the nested for loop (because x>2 is not fulfilled), thus primes.add(i) will not get executed.
Hint: A better way to print prime numbers 2...N is to use sieve approach: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
Edit: After re-evaluation, I've realized your logic is a bit off throughout. The code should actually read:
for (int i = 2; i < n; i++){
for(int x = 2; x <= i; x++)
if(i == x)
primes.add(i);
else if(i % x == 0)
break;
}
After testing this, it appears to work correctly.
When i = 2 or 3, x is < 2 and the inner for loop doesn't execute.
I'd change x to count up from 2:
for (int i = 2; i < n; i++){
for(int x = 2; x <= i; x++)
if( x == i)
primes.add(i);
else if (i % x == 0)
break;
}
return primes;
}
Typing this out on an iphone is terrible.
Inner for loop won't execute values less than 2. So, you have to initialize x =2; in inner for loop.
for(int x = 2; x <= i; x++)
Try this.

Unexpected output from while loop Java

This is the class whose behaviour I am unable to understand.
class loop1 {
public static void main(String args[]) {
int i = 10;
do
while(i++ < 15) {
System.out.println(i);
i = i + 20;
System.out.println(i);
}
while(i<2);
System.out.println(i);
}
}
I expected it to print
11
31
31
But it prints
11
31
32
I am not able to understand why this "32" has come up in the output.
This is my understanding of the flow
i = 10
In the while loop because of unary incremental, it becomes 11 so this explains the first output
11 gets incremented to 31 by (+20)
Then 31 < 15 should fail (during the next iteration) so it should proceed to the last print statement and print 31, but it instead it is printing 32.
Can someone tell me what I am missing ?
During the final evaluation of the first while loop i++ still increments i even though the loop does not execute because the condition fails.
class loop1 {
public static void main(String args[]) {
//1. i = 10
int i = 10;
do
// 2. while loop condition = (10 < 15), i = 11
// 6. while loop condition = (31 < 15), i = 32
while(i++ < 15) {
System.out.println(i); //3. prints 11
i = i + 20; //4. i = 31
System.out.println(i); //5. prints 31
}
while(i<2); //this really has no effect on the codes execution, given i values
System.out.println(i); //7. Prints 32
}
}
i++
You're increasing the value by 1. The value, when you increase it after the first iteration is 31. 31 + 1 is, surprisingly, 32. And you print out the value directly after incrementing it.
In 2nd iteration when condition of while loop is check
while(i++<15)
at that time i is 31 so condition fail but i++ change the value of i 31 -> 32
while(i++ < 15) compare the value of i with and after that increment i by 1
My guess is:
while(i++ < 15)
The i++ increments the value from 31 to 32 on the second loop.
Note, the ++ will be executed even if the condition fails - which in your case, the 31 is greater than 15 (condition fails), however because of the ++ the value is incremented to 32, which is being printed out by the System.out at the end.
In the program :
while(i++<15)
above statement is condition checking in this statement
you are post increment i therefor 31+1=32 is comming

Categories