what is wrong with this java code? [closed] - java

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I was going through an ICPC question HERE
The problem boils down to finding maximum.'s which can be achieved with K operations in a matrix having * and . such that we are allowed to toggle elements in a row in one operation.I first toggled the rows which result in positive or zero(toggling a row 2 times gives 0 change) change in *'s in decreasing order. At the end, if there is 1 toggle left, toggle the row with the least absolute value amongst the rows having negative changes.
Here is my code - BELOW CODE IN IDEONE.COM WITH SOME TEST CASES
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (t = t; t > 0; t--) {
int n = sc.nextInt();
int m = sc.nextInt();
int k = sc.nextInt();
char[][] array = new char[n][m] ;
int[] tracker = new int[n];
int[] trackerl = new int[n];
int i,j;
for (i = 0; i < n; i++) {
String temp = sc.next();
for (j = 0; j < m; j++) {
array[i][j] = (temp.charAt(j));
}
}
int light = 0, diamond = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (array[i][j] == '*') {
diamond++;
}
}
tracker[i] = diamond;
diamond = 0;
}
int a, b;
int temp;
int sortTheNumbers = n;
for (a = 1; a < sortTheNumbers; a++) {
for (b = 0; b < sortTheNumbers-a; b++) {
if (tracker[b] > tracker[b + 1]) {
temp = tracker[b];
tracker[b] = tracker[b + 1];
tracker[b + 1] = temp;
}
}
}
for (i = 0; i < n; i++)
trackerl[i]=m-tracker[i];
int br = 0;
try {
if (m % 2 == 0) {
for ( i = 0; i <= n - 1; i++)
if (tracker[i] > (m) / 2)
br++;
}
if (m % 2 !=0 ) {
for (i = 0; i <= n - 1; i++)
if (tracker[i] >= (m + 1) / 2)
br++;
}
} catch (Exception e) {
}
int ans = 0;
try {
if (br >= k) {
for (i = n - 1; i > (n - 1 - k); i--)
ans += tracker[i];
for (i = (n - 1 - k); i >= 0; i--)
ans += trackerl[i];
}
if (br < k) {
if (br != 0 && br != n) {
for (i = n - 1; i > (n - br); i--) {
ans += tracker[i];
k--;
}
int pass1 = 0, pass2 = 0;
if (k % 2 == 0)
pass1 = Math.max(tracker[(n - br)] + tracker[(n - br - 1)],
trackerl[(n - br)] + trackerl[(n - br - 1)]);
if (k % 2 != 0)
pass2 = Math.max(tracker[(n - br)] + trackerl[(n - br - 1)],
trackerl[(n - br)] + tracker[(n - br - 1)]);
// System.out.print("Hp" + tracker[(n - br)]);
}
ans += Math.max(pass1, pass2);
for (i = (n - 2 - br); i >= 0; i--)
ans += trackerl[i];
}
if (br != 0 && br == n) {
for (i = n - 1; i > (n - br); i--) {
ans += tracker[i];
k--;
}
if (k % 2 != 0) {
ans += tracker[(n - br)];
}
if (k % 2 == 0) {
ans += trackerl[(n - br)];
}
for (i = (n - 1 - br); i >= 0; i--) {
ans += trackerl[i];
}
}
if (br == 0) {
if (k % 2 != 0) {
ans += tracker[(n - 1)];
}
if (k % 2 == 0) {
ans += trackerl[(n - 1)];
}
for (i = (n - 2); i >= 0; i--) {
ans += trackerl[i];
}
}
}
} catch (Exception e) {
}
System.out.println(""+ans);
}
}
}
Whichever test case I choose gives the correct answer. I maintained variety in my test cases, as you can see from the link.Still the code isn't correct as it is not accepted by the judge. I really can't find where is the flaw.Is it in my code or my logic? Please point it out for me.

Writing code is the same as writing a paper, there are grammar, spelling, punctuation, and other rules which make the code readable and the point clear. Studying these and writing clear code pays off, not just for others who need to read your code, but for you too (you will see more of your own errors).
I'll just point out a few items I ran across when formatting your code. (Examples are from memory and not your code)
if(x=3;y>(2-2-x);y++)
Don't write a line like this because
if is not a function, and choosing "if(" over "if (" makes it look a little more like a function. The same goes with the keyword while.
Putting multiple strings of arithmetic operations (especially '+' and '-') in a long line (as in "(2-2-x)" confuses the dual roles that the '-' character can play, you would be better off putting in spaces "(2 - 2 - x)" to make the reader realize that we are dealing with multiple subtractions, without a unary negation operation (negative number).
if statements require three parameters (separated by semicolons). putting in spaces after each parameter can signal the reader that they are in the "next" parameter. Favour "if (x=3; y>(2-2-x); y++)" over "if (x=3;y>(2-2-x);y++)".
In the continued example
if(x=3;y>(2-2-x);y++)
{x=3;y=2;}
The brackets on the following line create reading comprehension issues.
They are subject to the same formatting problems as having no brackets after an if statement. By putting your entire block on a line, you confuse blocks and lines, and any line reordering will dramatically affect the operation of your program. This is bad. To fix this, favour "if (x = 3; y >(2 - 2 - x); y++) {".
There is a compound statement on a single line which mimics the formatting of the if statement above it, which could confuse a reader into believing that this is part of a subsequent nested if statement. It is far more readable to put the two assignment statements on their own lines.
You tie the end of the block to a statement, which couples the block boundaries to a particular operation. Often one needs to update their code, and odds are slim that the statement and end of the block should be connected over the lifetime of the program. Favour putting the end of block delimiter on a non statement line.
All of the above points, when used together, result in code that looks like
if (x = 3; y > (2 - 2 - x); y++) {
x = 2;
y = 3;
}
After some simple formatting, it is clear that you have multiple blocks of "if this, then that". It is also clear that lots of these blocks follow a pattern, "If this, then that. If not this, then that". The language has a built-in ability to handle such a pattern with an "else" block attached to the prior if block.
(example directly from your code)
if (k % 2 != 0) {
ans += tracker[(n - 1)]
}
if (k % 2 == 0) {
ans += trackerl[(n - 1)];
}
which could much more cleanly be written
if (k % 2 != 0) {
ans += tracker[(n - 1)]
} else {
ans += trackerl[(n - 1)];
}
or, using reordering to emphasize the equality over the inequality
if (k % 2 == 0) {
ans += tracker1[(n - 1)]
} else {
ans += tracker[(n - 1)];
}
One could go on, but after you make changes like these, really your code is starting in a much better place, so it doesn't make sense to talk about higher level techniques of making your code readable until some of the basics are done. Even so, I will recommend that you use full words for your variable names that attempt to describe the variable's purpose.
Good luck, and in my reformatting, I might have clipped a closing block delimiter (they don't match up) or maybe it wasn't there in the first place (not like one could check in the unformatted version).

Related

Calculate the number of Primes that are less than the given Number [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 months ago.
Improve this question
I'm getting desired output, but I'm not able to submit the code on the Leetcode.
The link of question on the Leetcode
Problem statement:
Given an integer n, return the number of prime numbers that are
strictly less than n.
Constraints:
0 <= n <= 5 * 10 ^ 6
My code:
class Solution {
public static int count = 1;
public int countPrimes(int n) {
if (n == 0 || n == 1 || n == 2)
return 0;
else
for (int i = 3; i < n; i++) {
for (int j = 2; j < i; j++) {
if (i % j == 0) {
break;
} else if (j == i - 1 && i % j != 0) {
count++;
}
}
}
return count;
}
}
It gives the desired result all the time but when I try to submit it, it shows that only 4/66 tests cases are passed.
Can someone please tell me what's wrong here and why I'm not able to submit the solution?
Don't use static variables without any good reason. count will live in memory until the application runs and will be effected by every invocation of countPrimes() with argument n greater than 3. Even if Leetcode creates a new instance of the Solution for every test (can't check it because I'm not registered there), static variable would maintain the previously assigned value because it doesn't belong to any instances of Solution, but shared among them all.
You will definitely not encounter this issue (but potentially there could be others related to performance) if variable count would be local - i.e. declared inside the countPrimes().
Condition if (n == 0 || n == 1 || n == 2) can be simplified to if (n <= 2). And there's no need to use else clause because you are returning if condition matches.
Similarly, there's no need for the else clause in the nested loop after the break.
So your code can be written like this:
public int countPrimes(int n) {
if (n <= 2) {
return 0;
}
int count = 1;
for (int i = 3; i < n; i++) {
for (int j = 2; j < i; j++) {
if (i % j == 0) break;
if (j == i - 1 && i % j != 0) {
count++;
}
}
}
return count;
}
There are several enhancements we can make to improve performance.
Not every Number is Prime - reducing the number of iterations
As obvious, not every number is prime. The most simple observation we can make is that 2 is the only even number among primes. And if the candidate number is greater than 2 we can skip all even numbers by incrementing the index of the loop by 2.
The next interesting property of primes that we can make use of is that there's no gap between the two first primes - the next prime after 2 is 3. Which means if the candidate number is greater than 3 we don't need to check numbers that are divisible by 2 and by 3.
I.e. we can omit 4 of every 6 consecutive numbers, in other words the candidate number can be represented as N * 6 - 1 and N * 6 + 1, these pair of number will not be divisible neither by 2, no by 3.
To achieve that, we can initialize the loop variable to 6 - int i = 6 and increment it at each iteration step by 6 - i += 6, and at every step of iteration (which would represent the next range of 6 number) we need to check the candidate number against two values: i - 1 and i + 1.
Another improvement we can make is connected with condition j < i. For a large input value n this condition will cause a lot of fruitless iterations because there would be no prime divisors for any given number i greater than sqrt(i) see.
And solution will be more readable if we split the method into two logical parts based on responsibilities: a method that is responsible for checking whether a candidate number is prime, and a method that tracks the number of discovered primes.
public int countPrimes(int n) {
if (n < 3) return 0;
if (n == 3) return 1;
if (n == 4) return 2;
int count = 2;
for (int i = 6; i <= n + n % 6; i += 6) {
if ((i - 1) < n && isPrime(i - 1)) {
count++;
}
if ((i + 1) < n && isPrime(i + 1)) {
count++;
}
}
return count;
}
public boolean isPrime(int candidate) {
if (candidate % 2 == 0 || candidate % 3 == 0) return false;
if (candidate == 5) return true;
if (candidate % 5 == 0) return false;
boolean isPrime = true;
double sqrt = Math.sqrt(candidate);
for (int i = 6; i <= sqrt; i += 6) {
if (candidate % (i - 1) == 0 || candidate % (i + 1) == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
This solution will be faster than the initial version, but we can do better.
Don't recalculate the same Primes
There's no need to recalculate the same prime numbers over and over while checking a candidate number.
Instead, we can store every discovered prime number into a list and then check every candidate number against the previously encountered primes from the list.
public int countPrimes(int n) {
if (n < 3) return 0;
if (n == 3) return 1;
if (n == 4) return 2;
List<Integer> primes = new ArrayList<>();
Collections.addAll(primes, 2, 3); // this line will be executed only if n > 4, hence we need to add primes 2 and 3 into the list
// we don't need variable `count` anymore, instead we can check the size of primes
for (int i = 6; i <= n + n % 6; i += 6) {
if (i - 1 < n && isPrime(i - 1, primes)) {
primes.add(i - 1);
}
if (i + 1 < n && isPrime(i + 1, primes)) {
primes.add(i + 1);
}
}
return primes.size();
}
public boolean isPrime(int candidate, List<Integer> primes) {
boolean isPrime = true;
double sqrt = Math.sqrt(candidate);
for (int i = 0; i < primes.size() && primes.get(i) < sqrt; i++) {
if (candidate % primes.get(i) == 0) {
isPrime = false;
break;
}
}
return isPrime;
}

Common Subsequence in Different Length Arrays

I've implemented a DP algorithm that finds the longest common subsequence in three arrays. The problem though, is that my algorithm doesn't work when the arrays are of different lengths, and I have no idea why. From what I can tell, my algorithm is correct, so I think it's something to do with the Java implementation. Here is my Java code:
static int[] lcsOf3(int[] X, int[] Y, int[] Z, int xLength, int yLength, int zLength) {
int[][][] S = new int[xLength + 1][yLength + 1][zLength + 1];
for (int i = 0; i <= xLength; i++) {
for (int j = 0; j <= yLength; j++) {
for (int k = 0; k <= zLength; k++) {
if (i == 0 || j == 0 || k == 0) {
S[i][j][k] = 0;
} else if (X[i - 1] == Y[j - 1] && X[i - 1] == Z[k - 1]) {
S[i][j][k]= S[i - 1][j - 1][k - 1] + 1;
} else {
S[i][j][k] = Math.max(Math.max(S[i - 1][j][k], S[i][j - 1][k]), S[i][j][k - 1]);
}
}
}
}
System.out.println(S[xLength][yLength][zLength]);
}
I took another look at my code,and it turns out that it was something with my implementation, not the algorithm itself. There was a bug in the part of my code that gets the input arrays(X,Y,Z). After fixing the bug, it works correctly on lists of different sizes.
Thanks to everyone who tried to help out, and sorry for wasting your time.

What is wrong with this program?I need to find addition of all the odd numbers and even numbers using while

I need to find sum of even and odd numbers from 0 to 50 using While Statement,here is my code
During runtime..I do not get any output from the compiler ..Help please
import java.util.Scanner;
class Odd_Even
public static void main(String args[])
{
int i = 1, j = 1, oddsum = 0, evensum = 0;
while (i <= 50) {
if (i % 2 == 0) {
evensum = i + evensum;
i = i + 1;
}
}
System.out.println("Answar of the Even number is=" + evensum);
while (j <= 50){
if (j % 2 == 1){
oddsum = j + oddsum;
j = j + 1;
}
}
System.out.println("sum of odd number is="+oddsum);
}
}
You need to take the lines that increment your loop variables out of your if statements. Otherwise the loop variables will never be incremented:
while (i <= 50) {
if (i % 2 == 0) {
evensum = i + evensum;
}
i = i + 1;
}
System.out.println("Answar of the Even number is=" + evensum);
while (j <= 50){
if (j % 2 == 1){
oddsum = j + oddsum;
}
j = j + 1;
}
This problem could have been found rather easily if you attached a debugger to your program and stepped through the code. Step-through debugging is an invaluable tool that every developer should know how to use!

Is it possible to implement a BubbleSort with only one cycle? (Not recursive)

What Im trying to implement is a BubbleSort/similar algorithm, but with just one single cycle.
What that means is, I want to change this:
for (i = 0; i < N - 1; i++)
for(j = i+1; j < N; j++)
//code
into this:
for (ij = 0; ij < N * (N - 1) / 2; ij++)
i = ?
j = ?
//code
The problem is, I need to implement the values of 'i' and 'j' manually. Does anybody know if this is possible?
Assuming you meant i+1, not 1+1, the code
for (i = 0; i < N - 1; i++)
for(j = i+1; j < N; j++)
//code
is equivalent to
int k = 2 * N - 1;
for (int ij = 0; ij < N * (N - 1) / 2; ij++) {
int i = (int) Math.floor((k - Math.sqrt(k * k - 8 * ij)) / 2);
int j = i + 1 + ij - (k - i) * i / 2;
//code
}
This is completely pointless though...
You could do it like this:
while (ij < N * (N - 1) / 2) {
j = (j + 1) % N;
if (j==0)
i++;
}
I don't see the benefit though
Here is a while-loop version, though I also don't see the point. Generally, you can turn almost anything into one loop by having a boolean that indicates whether to continue, and various if-tests to decide what to do inside the loop. If applied to a naturally nested loop algorithm, the result will be less readable and maintainable than using multiple loops.
public static void weirdSort(int[] data) {
boolean sortDone = false;
boolean swapDone = false;
if (data.length < 2) {
// Lengths 0 and 1 create special cases, and are already sorted.
return;
}
int i = 0;
while (!sortDone) {
if (data[i] > data[i + 1]) {
swapDone = true;
int temp = data[i + 1];
data[i + 1] = data[i];
data[i] = temp;
}
i++;
if (i == data.length - 1) {
sortDone = !swapDone;
swapDone = false;
i = 0;
}
}
}

Output an ASCII diamond shape using loops

I am trying to write a program in Java that captures an integer from the user (assume data is valid) and then outputs a diamond shape depending on the size of the integer, i.e. User enters 5, output would be:
--*--
-*-*-
*---*
-*-*-
--*--
So far I have:
if (sqr < 0) {
// Negative
System.out.print("#Sides of square must be positive");
}
if (sqr % 2 == 0) {
// Even
System.out.print("#Size (" + sqr + ") invalid must be odd");
} else {
// Odd
h = (sqr - 1) / 2; // Calculates the halfway point of the square
// System.out.println();
for (j = 0; j < sqr; j++) {
for (i = 0; i < sqr; i++) {
if (i != h) {
System.out.print(x);
} else {
System.out.print(y);
}
}
System.out.println();
}
}
Which just outputs:
--*--
--*--
--*--
--*--
--*--
I was thinking about decreasing the value of h but that would only produce the left hand side of the diamond.
void Draw(int sqr) {
int half = sqr / 2;
for (int row = 0; row < sqr; row++) {
for (int column = 0; column < sqr; column++) {
if ((column == Math.abs(row - half))
|| (column == (row + half))
|| (column == (sqr - row + half - 1))) {
System.out.print("*");
} else {
System.out.print("_");
}
}
System.out.println();
}
}
Ok, now this is the code, but as I saw S.L. Barth's comment I just realised this is a homework. So I strongly encourage you to understand what is written in this code before using it as final. Feel free to ask any questions!
Take a look at your condition:
if (i != h)
This only looks at the column number i and the midway point h.
You need a condition that looks at the column number and the row number. More precisely, you need a condition that looks at the column number, the row number, and the distance of the column number from the midway point.
Since this is a homework question, I leave determining the precise formula to you, but I'm willing to drop some more hints if you need them. Good luck!
You can use two nested for loops from -h to h, where h is half a diamond. The edge of a diamond is obtained when:
Math.abs(i) + Math.abs(j) == h
If user input n=5, then h=2, and a diamond looks like this:
n=5, h=2
--*--
-*-*-
*---*
-*-*-
--*--
Try it online!
// user input
int n = 9;
// half a diamond
int h = n / 2;
// output a diamond shape
System.out.println("n=" + n + ", h=" + h);
for (int i = -h; i <= h; i++) {
for (int j = -h; j <= h; j++) {
if (Math.abs(i) + Math.abs(j) == h) {
System.out.print("*");
} else {
System.out.print("-");
}
}
System.out.println();
}
Output:
n=9, h=4
----*----
---*-*---
--*---*--
-*-----*-
*-------*
-*-----*-
--*---*--
---*-*---
----*----

Categories