I want to simplify this if-Statement and prevent writing "!='*'" three times. Is it possible?
if (i != '*' && j != '*' && k != '*')
use arrays:put all elements into the array, traverse the array and judge。
List<String> list = new LinkedList<>(Arrays.asList(i,j,k));
if(list.stream().noneMatch("*"::equals)){
}else{
}
use string: splice elements into a string
String temp = i+j+k;
if(temp.contains("*")){
}
I want to simplify this if-Statement and prevent writing "!='*'" three times.
Here is a solution that simplifies the readability and intent.
First, make a simple, obvious method with a clear name (bonus: this is easy to write unit tests around):
private static boolean isValid(char i) {
return i != '*';
}
Then in your calling code, do this:
if (isValid(i) && isValid(j) && isValid(k)) {
// do things if all are valid
}
You can further improve the readability by making a single method which checks isValid() for an array of characters:
private static boolean allAreValid(char[] chars) {
for (char ch : chars) {
if (!isValid(ch)) {
return false;
}
}
return true;
}
Then your calling code becomes really clear, not just the steps but also the intent – proceed with the body of the if statement only if the characters are all valid.
char[] chars = {i, j, k};
if (allAreValid(chars)) {
// do things if all are valid
}
Yes it is possible to omit writing !='*' three times but the method will be still longer one. I would suggest to use the method which you have written in your question but if you really want to try something other out (maybe out of curiosity), you can do this:
char ch[] = {i,j,k}; /*I hope the variables i,j,k in question are char type*/
boolean flag = false;
for(int t = 0; t < ch.length; t++){
if(ch[t] != '*')
flag = true;
else{
flag = false;
break;
}
}
if(flag){
//Tasks to do...
}
Writing this much is a tedious job. Thus, if (i != '*' && j != '*' && k != '*') is the most optimised one. So I would recommend using it.
I have the following code on a huge project. I want to find a better implementation to avoid the same code
if(CConst.CONST1.equals(SOMETHING1)){
const1fieldsaver = true;
if(a != 0){
//same code
if(value <= 0){
const1field = ...//same code
}
}
if(CConst.CONST2.equals(SOMETHING2)){
const2fieldsaver = true;
if(a != 0){
//same code
if(value <= 0){
const2field = ...//same code
}
}
how can i avoid these to if statements? The have the same code but as you can see it save the values to different variables. Is there any more efficient way to implement this?
I would suggest creating a method that you call inside each if block that executes the code you want.
if(CConst.CONST1.equals(SOMETHING1)){
const1fieldsaver = true;
if(a != 0){
executeSameCode(); //calling method here
if(value <= 0){
const1field = ...executeSameCode2(); //calling method, note that it is different from above method.
}
}
if(CConst.CONST2.equals(SOMETHING2)){
const2fieldsaver = true;
if(a != 0){
executeSameCode();
if(value <= 0){
const2field = ...executeSameCode2();
}
}
//somewhere else inside the class
public void executeMethod() {
//your code
} //can be made to return stuff
public void executeMethod2() {
//your code
} //again, can be made to return stuff
This way, you don't need to set up lots of temporary variables, but instead, just call the method from wherever you want.
Hope that helped!
If possible,
assign conditions directly to booleans and merge If-Statements.
e.g.
const1fieldsaver = CConst.CONST1.equals(SOMETHING1);
if(const1fieldsaver && a != 0 && value <= 0) {
const1field = ...
}
For more complex conditions I would use functions as recommended by Ted Lyngmo.
I am Solving Partition Equal Subset Sum of leetcode.
Problem States:
Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.
Note:
Each of the array element will not exceed 100.
The array size will not exceed 200.
I Wrote the Code for the following as
class Solution {
public boolean canPartition(int[] nums) {
int sum=0;
for(int i=0;i<nums.length;i++)
{
sum=sum+nums[i];
}
if(sum%2!=0)
{
return false;
}
int target=sum/2;
return helper(nums,target,nums.length);
}
boolean helper(int nums[],int sum,int n)
{
if(sum==0)
{
return true;
}
if(sum<0)
{
return false;
}
if(n==0)
{
return false;
}
return helper(nums,sum-nums[n-1],n-1)||helper(nums,sum,n-1);
}
}
Notice that I did not included the condition
if(sum<nums[n-1])
{
return false;
}
in the base case as i have included
if(sum<0)
{
return false;
}
which is the same thing as it would just add 1 more recursive call and then return false.
This code works for 89 of the test cases but gives TLE error for
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,100]
Now if the modify the same code and include
if(sum<nums[n-1])
{
return false;
}
and remove
if(sum<0)
{
return false;
}
i.e
class Solution {
public boolean canPartition(int[] nums) {
int sum=0;
for(int i=0;i<nums.length;i++)
{
sum=sum+nums[i];
}
if(sum%2!=0)
{
return false;
}
int target=sum/2;
return helper(nums,target,nums.length);
}
boolean helper(int nums[],int sum,int n)
{
if(sum==0)
{
return true;
}
if(n==0)
{
return false;
}
if(nums[n-1]>sum)
{
return false;
}
return helper(nums,sum-nums[n-1],n-1)||helper(nums,sum,n-1);
}
}
The code works fine and passes all the Test Cases.
Since both the code are same how is that one extra recursive call giving me TLE?
Is there is something else ?
The test cases are really weak. First one should get TLE as you did not use dynamic programming but performed a plain backtrack. Second one should get WA. If you used memoization your complexity would be O( totalSum * arraySize) but the complexity of your code is O(2 ^ arraySize).
now observe you have two options in every state. Either you pick the element or not. Even if this condition is true if(nums[n-1]>sum) , the second option is valid - going forward not picking the item. But your second code ignores both the cases for that condition reducing the calls to the point your solution takes less than 1 millisecond which is faster than most correct solution. As there was no counter test cases for the second solution it passed.
Is there a tool or a way to count the number of branches in a given Java class? For example, I want to count the number of branches in the following simple Java class:
public class Testt {
public boolean getTest(int x) {
if (x > 5) {
return true;
} else {
return false;
}
}
public int getTest1(int x) {
int t = 0;
if (x == 10) {
t = 1;
} else if (x == 8) {
t = 3;
} else {
t = 11;
}
return t;
}
}
The term you are looking for is "cyclomatic complexity".
Cyclomatic complexity is a software metric (measurement), used to
indicate the complexity of a program. It is a quantitative measure of
the number of linearly independent paths through a program's source
code.
If you are using Eclipse as your IDE there is a plugin called Eclipse Metrics that can give this kind of information.
I have the following code. The only problem is that we run it through a checkstyle program and it comes up with the error Cyclomatic Complexity is 11 (max allowed is 10). I would like to know how can remove one of the if statement to make it do the same thing and let the program pass the test.
/**
* Check if there is a winner on the board
* #return the winner if BLANK there is no winner
**/
public char checkWinner(){
this.winner = BLANK;
int totalTiles = GRIDSIZE*GRIDSIZE;
//Check if the game has a win
for (int i=0; i < GRIDSIZE; i++) {
if((grid[i][0] == grid[i][1]) && (grid[i][1] == grid[i][2])){
winner = grid[i][0];
return winner;
}
if((grid[0][i] == grid[1][i]) && (grid[1][i] == grid[2][i])){
winner = grid[0][i];
return winner;
}
}
if((grid[0][0] == grid[1][1]) && (grid[1][1] == grid[2][2])){
winner = grid[0][0];
return winner;
}
if((grid[0][2] == grid[1][1]) && (grid[1][1] == grid[2][0])){
winner = grid[0][2];
return winner;
}
//Check if the game is a tie
if (movesMade == totalTiles){
winner = TIE;
}
return winner;
}
I don't know how the checker works but how about this:
if(((grid[0][0] == grid[1][1]) && (grid[1][1] == grid[2][2])) ||
((grid[0][2] == grid[1][1]) && (grid[1][1] == grid[2][0]))) {
winner = grid[1][1];
return winner;
}
If this does work, the irony of course is that this seems a little less readable than your code.
You could extract methods for checking rows and column and rewrite your code something like this:
public char checkWinner()
{
for (int i=0; i < GRIDSIZE; i++) {
if (checkRow(i)) return winner;
if (checkColumn(i)) return winner;
}
if (checkDiagTopLeft()) return winner;
if (checkDiagBottomLeft()) return winner;
}
Easier to read and less complexity.
Side note: Obviously, the winner stuff could use a redesign, but that was not part of the question and is left as an exercise for the reader (and commenters) if they feel like it.
The solution is already up there (combining the if statements), but I would not let Cyclomatic Complexity dictate my coding if the code of a method fits on a single page. The measure you want to aim for in a big project is readability and ease of understanding. Remember that code will be written potentially only once, but read quite a few times.
The first step can be to remove some redundancy from the equal expression. The allEqual makes the intent a bit clearer.
Assinging the winner to a field is strange. I've removed that in the refactoring. If you really need the assignment you could do it in a separate method calling checkWinner. The problem with returning and assigning is that it's unexpected for a caller to have this side effect.
public char checkWinner() {
// Check if the game has a win
for (int i = 0; i < GRIDSIZE; i++) {
if (allEqual(grid[i][0], grid[i][1], grid[i][2])) return grid[i][0];
if (allEqual(grid[0][i], grid[1][i], grid[2][i])) return grid[0][i];
}
if (allEqual(grid[0][0], grid[1][1], grid[2][2])) return grid[0][0];
if (allEqual(grid[0][2], grid[1][1], grid[2][0])) return grid[0][2];
// Check if the game is a tie
int totalTiles = GRIDSIZE * GRIDSIZE;
return movesMade == totalTiles ? TIE : BLACK;
}
private boolean allEqual(char... c) {
for(int i=1;i<c.length;i++) if(c[i-1] != c[i]) return false;
return true;
}
Open Problems:
The char[][] array is not the most efficient data structure to represent the board. You could use a BitSet.
You defined GRIDSIZE constant but you're could would break down if you actually changed it from 3 to another value.
You can use the fact that checking row/columns and diagonals is symmetric. The parameters have to be transposed use this.
Using the GRIDSIZE constant you do not have to address all cells explicitly:
public char checkWinner() {
// Check if the game has a win
for (int i = 0; i < GRIDSIZE; i++) {
if (rowEqual(i)) return grid[i][0];
if (columnEqual(i)) return grid[0][i];
}
if (diagonalLeftToRightEqual()) return grid[0][0];
if (diagonalRightToLefttEqual()) return grid[0][GRIDSIZE];
// Check if the game is a tie
int totalTiles = GRIDSIZE * GRIDSIZE;
return movesMade == totalTiles ? TIE : BLACK;
}
private boolean rowEqual(int r) {
for(int i=1;i<GRIDSIZE;i++) if(grid[r][i-1] != grid[r][i]) return false;
return true;
}
private boolean diagonalLeftToRightEqual() {
for(int i=1;i<GRIDSIZE;i++) if(grid[i-1][i-1] != grid[i][i]) return false;
return true;
}
Cyclometric complexity is a measure of the number of paths through your code. Your function is composed almost exclusively of if statements.
You can combine two or more if statements with or:
if(a)
do_something();
if(b)
do_something();
Should be replaced by:
if(a || b)
do_something();