Studying if/else vs if/if statement - java

I was trying to write a code where all the 0s will be moved to the right of the array. I just used a left and a right pointer.
public class Solution {
public int[] moveZero(int[] array) {
// Write your solution here
if (array.length==0) {
return array;
}
int left=0;
int right=array.length-1;
while (left<=right) {
if (array[left]!=0) {
left+=1;
}
if (array[right]==0) {
right-=1;
} else {
int temp = array[left];
array[left] = array[right];
array[right] = temp;
left+=1;
right-=1;
}
}
return array;
}
}
I know here I should use the if/else if instead of if/if, that's why I have the index out of the bound error. But I don't understand why? If I have the if/if statement, what's the difference does that make rather than using if/else if in this question?

if (condition1) {
a();
} else if (condition2) {
b();
} else {
c();
}
means the same as
if (condition1) {
a();
} else {
if (condition2) {
b();
} else {
c();
}
}
So else if is just shorthand for an else with an if inside.
To understand why your code throws an ArrayIndexOutOfBoundsException, the easiest way is stepping through the code in a debugger (consult the documentation of your development environment for how to do this).
Alternatively, you can pretend you are a computer, and execute the program with pen and paper to figure out where your program goes off the rails. However, using a debugger is easier once you know how to use one.

I don't think there's any reason to use if/else instead of if/if, they both have their place. In an if/if statement, if the second if statement relies on the previous being false, then it should be converted to an if/else statement. If the else statement in an if/else statement has nothing to do with the if statement before it, then it should be converted into two separate if statements.
As an example of when to use an if/else statement (to do the same thing yours does):
public class Solution {
public int[] moveZero(int[] inputArray) {
int[] outputArray = new int[inputArray.length];
int left = 0;
int right = inputArray.length - 1;
for (int num : inputArray) {
if (num == 0) {
outputArray[right] = num;
right --;
} else {
outputArray[left] = num;
left ++;
}
}
return outputArray;
}
}

Related

Parametrisation of recursive method without global variable

As an example we're combing through the permutations of the integer 123456789. Inspired by Heap's algorithm, we have the following
public static ArrayList<String> comb(char[] seq, int n, ArrayList<String> box){
if(n == 1){
if (isSquare(Integer.valueOf(String.valueOf(seq)))) {
box.add(String.valueOf(seq));
}
} else {
for(int i=0; i<n; i++){
comb(seq,n-1, box);
int j;
if ((n%2)==0) {
j = i;
} else {
j = 0;
}
char temp = seq[n-1];
seq[n-1] = seq[j];
seq[j] = temp;
}
}
return box;
}
In the present case we're interested whether a particular permutation is a square of an integer. Realised by
public static boolean isSquare(int n) {
if ((n%10)==2 || (n%10) ==3 || (n%10)==7 || (n%10) == 8) {
return false;
} else if ( (Math.sqrt(n)) % 1 ==0) {
return true;
} else {
return false;
}
}
However, to be able to use comb I must initialise an empty array outside of the method. What should I do to avoid inducing the need for global variable? I would still like to obtain a box with all solutions. I realise my error is in the parametrisation of comb .
Create a function that "wraps" the original recursive function, provides it with every parameter it needs and creates copies of objects if necessary:
Let's say you renamed your comb(...) function to combRecursive(...) for the sake of convenient naming.
public static ArrayList<String> comb(char[] seq, int n){
char[] seqCopy = Arrays.copyOf(seq, seq.length);
return combRecursive(seqCopy, n, new ArrayList());
}

Quick Program help (quick fix)

I have a homework assignment where I need to make an array of lightbulb objects. Then add a method to "turn them on". I need to have a nested loop to have an imaginary person turn on every bulb then pull the string on every other bulb then every 3rd and so on until its every 20 bulbs. This is the code I have. It compiles but when I run it, it just goes forever. PLEASE HELP
public class LightBulb
{
public boolean isTurnedOn;
public LightBulb()
{
isTurnedOn = false;
}
public boolean isOn()
{
if(isTurnedOn==false)
return false;
return true;
}
public void pullString()
{
if(isTurnedOn==true){
isTurnedOn=false;
}
isTurnedOn=true;
}
}
public class LightDriver
{
public static void main(String[]arg)
{
int numOn=0;
LightBulb[]Bulb=new LightBulb[100];
for(int a=0;a<100;a++){
Bulb[a]=new LightBulb();
}
for(int b=0;b<=19;b++){
for(int c=0;c<=100;c=b+1){
Bulb[c].pullString();
}
}
for(int d=0;d<100;d++){
if(Bulb[d].isTurnedOn==true){
numOn++;
}
}
System.out.println(numOn+" lightbulbs are on");
}
}
This is causing the problem:
for(int b=0;b<=19;b++){
for(int c=0;c<=100;c=b+1){
Bulb[c].pullString();
}
}
For every iteration of the inner for loop, you are setting c = b + 1 which means that c is not changing, since b is not changing.
I think what you want is this:
for(int b=1; b <= 20; b++){
for(int c=0; c < 100; c = c + b){
Bulb[c].pullString();
}
}
Also, your pullString method sets isTurnedOn to true no matter what it originally was. I think this is what you want instead:
public void pullString()
{
if (isTurnedOn)
{
isTurnedOn = false;
}
else
{
isTurnedOn = true;
}
}
Your problem is in this loop
for(int b=0;b<=19;b++){
for(int c=0;c<=100;c=b+1){
Bulb[c].pullString();
}
}
your value of c never increases, as it is always set to b+1 which - within a single iteration of the b loop - never changes. As such, you never reach the termination condition of the loop. Here is a fix
for(int b=0;b<=19;b++){
int c = b+1; //assign initial value outside of inner loop
for(;c<=100;c++){ //increment value inside of inner loop
Bulb[c].pullString();
}
}

Using loops to return in a method

So, I need to return either a position in an array or a -1 if the goal number is not found. The problem is when I use return inside an if else statement, I get an error because the program will not go into the if loop. Here is my current code:
public int search(int num1)
{
for(int i=0;i<scores.length;i++)
{
if(scores[i]==num1)
{
return i;
}
else
{
return -1;
}
}
}
This keeps giving me an error saying no return statement. Is there a way to do this logic without the error?
thanks guys
If the for loop is not entered, then there is no return statement. This could happen if scores.length is 0. You must supply a return statement in all cases of execution, or the compiler will catch a case without a return statement and give a compiler error.
Move the return -1 after the for loop, so that you only return -1 if you went through the entire loop and didn't find num1. That also means that the else block is unnecessary -- remove it.
it gives you error because it might think that the loop might not be executed. in order for it to run it has to be a return statement outside a loop or an if statement.
here is an adjustment i did with your code.
public int search(int num1) {
int x = -1;
for(int i = 0; i < scores.length; i++) {
if(scores[i]==num1) {
x = i;
}
}
return x;
}

How to tell if an int has been changed

I want to know how to tell if an int has been changed (during the program).
Like with an if statement.
int i = 2;
int a = 1;
while(1 < 2) {
if(i % 100 == 0) i++;
}
if(i //Then checks if it changed) {
System.out.println("Changed :D");
}
Is there a way to tell if the variable i is changed DURING the program?
Since this is Java, are these variables data members of a class? In that case give them private access and provide getters and setters. Your setter can notify you if you so desire.
int i = 0;
boolean valueChanged = false;
while(some good condition) {
if (i % 100 == 0) {
i++;
valueChanged = true;
}
}
if(valueChanged) {
System.out.println("Changed :D");
}
// Your int variable
int i = 0;
// A scratch variable
int prev_value_of_i = i;
// Call this code to check whether i has changed since last call
if(i != prev_value_of_i) {
System.out.println("Changed :D");
prev_value_of_i = i;
}
Keep track of the original value of i in a separate variable and compare i to that?
This seems redundant, since the programmer should know when and where values are stored. If you don't, maybe step through with a debugger? #shoover's answer is the most flexible, handling however many unexpected times you might change the value without requiring adding lines of code inside your infinite loop.
class TalkativeInt{
private int x;
TalkativeInteger(int x){
this.x = x;
}
public void set(int a){
System.out.println("Changed!! "+x+" to "+a);
x = a;
}
public int get(){
//System.out.println("Accessed - that tickles");
return x;
}
}

Google javaparser IfStmt not counting consequent <else-if>

I am using Google javaparser to parse the java file, when I try to count the "If" statement, it seems like I can not get the number of "else-if" statement.
For example, I want to parse the following code:
if(i>1){
i++;
}else if(i>2){
i++;
}else if(i>3){
i++;
}else{
i++;
}
I want to get the Cyclomatic complexity so that I need to count the number of "if" and "else-if".
When I use Visitor pattern, I can only visit the "IfStmt" defined in the API, the code looks like:
private static class IfStmtVisitor extends VoidVisitorAdapter<Void> {
int i = 0;
#Override
public void visit(IfStmt n, Void arg) {
//visit a if statement, add 1
i++;
if (n.getElseStmt() != null) {
i++;
}
}
public int getNumber() {
return i;
}
}
There is no way to get "else-if" but the Visitor pattern with "IfStmt" treats the whole code block as one "if" Statement.So, I expect the number to be 4, but it is 2.
Anyone have some idea?
A if-statement only contains one "then Statement" and one "else Statement". The else Statement can be a hidden if statement. So there is a recursivity. To track your needed complexity the following recursive method may help:
private static class IfStmtVisitor extends VoidVisitorAdapter<Void> {
int i = 0;
#Override
public void visit(IfStmt n, Void arg)
{
cyclomaticCount(n);
}
private void cyclomaticCount(IfStmt n)
{
// one for the if-then
i++;
Statement elseStmt = n.getElseStmt();
if (elseStmt != null)
{
if ( IfStmt.class.isAssignableFrom(elseStmt.getClass()))
{
cyclomaticCount((IfStmt) elseStmt);
}
else
{
// another for the else
i++;
}
}
}
public int getNumber() {
return i;
}
}
Hope that helps.

Categories