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();
}
}
Related
I have an action listener that calls some methods and one of those methods counts the number of times that a loop inside of another method is run. The problem I am having is that the counter just adds to itself (I understand why I just don't know how to fix it) rather than resetting back to 0.
Here is my action listener code.
public double computeIterative(double n) throws InvalidInput {
int a=1, b=2;
int result = 0;
if (n>=0) {
if(n==0)return 0;
if(n==1)return 1;
if(n==2)return 2;
for(int i = 3; i <= n; i++) {
result = a+(2*b);
a=b;
b = result;
this.getEfficiency();
}
} else{
throw new InvalidInput();
}
return result;
}
ActionListener that calls methods and sets text:
public void actionPerformed(ActionEvent e) {
int n = Integer.parseInt(nField.getText());
//Try Catch for Iterate Radio Button
if (iterateBtn.isSelected()){
try {
double result = sequence.computeIterative(n);
int efficiency = sequence.getEfficiency();
rField.setText(Double.toString(result));
eField.setText(Integer.toString(efficiency));
}
catch (InvalidInput ex) {
}
}
The getEfficiency method counts how many times the loop inside computeIterative method is run and then sets it to a textField.
Here is my getEfficiency method:
public int getEfficiency() {
efficiency++;
return efficiency;
}
Now obviously this will just keep adding onto itself, and I am sure that I am looking way too hard for a solution but I just cant figure it out.
Basically, after the try, catch, I need to set efficiency to 0 so that the next time the computeIterative(n) method is called, I get a proper reading.
You could simply add a method resetEfficiency():
public int resetEfficiency() {
efficiency = 0;
}
And then call it at the beginning of computeIterative():
public double computeIterative(double n) throws InvalidInput {
this.resetEfficiency();
//rest of code goes here
//....
}
(Of course I'm assuming this is not multi-threaded or anything).
public double computeIterative(double n) throws InvalidInput {
int a=1, b=2;
int result = 0;
this.resetEfficiencyCounter(); //Call Reset if Number Got Invalid.
if (n>=0) {
if(n==0)return 0;
if(n==1)return 1;
if(n==2)return 2;
for(int i = 3; i <= n; i++) {
result = a+(2*b);
a=b;
b = result;
this.getEfficiency();
}
} else{
throw new InvalidInput();
}
return result;
}
add new Function Named resetEfficiencyCounter().
private void resetEfficiencyCounter(){
this.efficiency = 0;
}
import java.util.Random;
public class Mutation {
public Mutation()
{
}
private ArrayList<int[][]> allWords=new ArrayList<int[][]>();
public ArrayList<int[][]> wordGenrator(int noOfWords)
{
int rand,j;
int word[][]=new int[8][8];
for(int i=0;i<noOfWords;i++)
{
for(j=0;j<8;j++)
{
rand = new Random().nextInt(2);
System.out.print(rand);
word[i][j]=rand;
}
System.out.print("\n");
allWords.add(word);
}
return allWords;
}
public boolean isExistWordOfAllOnes()
{
int counter;
for(int i=0;i<5;i++)
{
counter=0;
for(int j=0;j<8;j++)
{
if(equals(this.allWords.get(i)[i][j]==1)
{
counter++;
}
}
if(counter==8)
{
return true;
}
}
return false;
}
The loop is running well, but this is not comparing correctly. I want to do if allword(i) have all 1's then return true otherwise false.
Now this is my whole code of same class.. I'm calling these functions in another main class...
As far as I read your code and your text I think you have a int[5][8] Array and you'd like to check whether there is at least one "1" in every row of the array or not. In that case you juse need to change the the Code as followed
public boolean isExistWordOfAllOnes()
{
int counter;
for(int i=0;i<5;i++)
{
counter=0;
for(int j=0;j<8;j++)
{
if(this.allWords.get(i)[i][j]==1)
{
counter++;
}
}
if(counter < 1) // If there were no 1's then count should still be 0
{ // and the method returns false as a row was found
return false; // in which there wasn't a 1
}
}
return true;
}
That ; should be a )
if(equals(this.allWords.get(i)[i][j]==1);
Also, the == is already comparing two things, thus the "equals" is not. Get rid of the equals.
This should be outside the for:
allWords.add(word);
With that change, there will only be one word[][], thus, change the i for a 1:
this.allWords.get(1)...
The problem is with 2D array initialization
What will be value of 2D array if noOfWords=1?
int word[][]=new int[8][8];
for(int i=0;i<noOfWords;i++)
{
for(j=0;j<8;j++)
{
rand = new Random().nextInt(2);
System.out.print(rand);
word[i][j]=rand;
}
System.out.print("\n");
allWords.add(word);
}
Look at the inline comments.
public boolean isExistWordOfAllOnes()
{
int counter;
for(int i=0;i<5;i++) // iterate all the words that are 2D arrays
{
counter=0;
for(int j=0;j<8;j++) // row
{
for (int k = 0; k < 8; k++) { // column
if (this.allWords.get(i)[j][k]==1) { // if it is equal to 1
counter++;
}
}
}
if(counter==8*8)//total 64 ones in 8*8 2D array
{
return true;
}
}
return false;
}
I'm creating a 4x4 2D array. I need to be notified, or gain a value when all elements have been turned true. Is this as simple as "If the2DArray[] = true { blah blah }" ?
Thanks!
P.S. I haven't wrote the code yet. I'm asking this question to help formulate the logic of the program.
For 2D arrays, you must manually go through all the elements in the array to check if one value will be false.
An example of this would be:
public boolean checkArr(boolean[][] arr) {
for(int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr[i].length; j++) {
if(!arr[i][j])
return false;
}
}
return true;
}
One way you could use to be notified when all array elements are true is by wrapping an array element in its own object that fires an on/off event, and wrapping the entire array in an object that fires an allOn event. Something like this (code is c#, but hopefully you can follow):
public class Element
{
public event Action TurnedOn = delegate { };
public event Action TurnedOff = delegate { };
private bool state;
public void TurnOn()
{
state = true;
TurnedOn();
}
public void TurnOff()
{
state = false;
TrunedOff();
}
}
public class My2DArray
{
public event Action AllTurnedOn = delegate { };
private readonly Element[,] array;
private int numberOfElementsThatHaveBeenTurnedOn;
public My2DArray(Element[,] array)
{
this.array = array;
foreach (Element element in array)
{
element.TurnedOn += OnElementTurnedOn;
element.TurnedOff += OnElementTurnedOff;
}
}
private void OnElementTurnedOn()
{
numberOfElementsThatHaveBeenTurnedOn++;
int amountOfElements = GetAmountOfElementsInArray();
bool allElementsAreOn = numberOfElementsThatHaveBeenTurnedOn == amountOfElements;
if (allElementsareOn)
{
AllTurnedOn();
}
}
private void OnElementTurnedOff()
{
numberOfElementsThatHaveBeenTurnedOn--;
}
}
The logic for counting if all elements have been turned on assumes that all elements are false to begin with.
If you want action to be taken in case all elements are true , you will have to check each element.
boolean flag=true;
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
if(array[i][j] == 'false')
flag=false;
return;
}
}
if(flag == true)
// your action
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;
}
}
I am trying to write a class that will remove a column from a 2d array, but I keep running into errors that I don't understand. I think I am misunderstanding something very basic here, any help would be appreciated
public class CollumnSwitch
{
int[][] matrix;
int temp;
public static void coldel(int[][] args,int col)
{
for(int i =0;i<args.length;i++)
{
int[][] nargs = new int[args.length][args[i].length-1];
for(int j =0;j<args[i].length;j++)
{
if(j!=col)
{
int temp = args[i][j];
}
nargs[i][j]= temp;
}
}
}
public void printArgs()
{
for(int i =0;i<nargs.length;i++)
{
for(int j =0;j<nargs[i].length;j++)
{
System.out.print(nargs[i][j]);
}
System.out.println();
}
}
}
You cannot access a non-static variable from a static context, you need to change int temp; to static int temp; or you can remove static from your method declaration.
You declare your nargs array in the coldel method, so it is not accessible from other methods. Meaning this doesn't work:
for(int i =0;i<nargs.length;i++) //You try to access nargs which is not possible.
{
for(int j =0;j<nargs[i].length;j++)
...
Maybe you want it to be the matrix array you have in your class? Like this:
in coldel:
matrix= new int[args.length][args[i].length-1];
and in printArgs
for(int i =0;i<matrix.length;i++)
{
for(int j =0;j<matrix[i].length;j++)
...
This require matrix to be static also (again, you can also remove static from coldel)
you can try like this:
static int[][] nargs;
public static void deleteColumn(int[][] args,int col)
{
if(args != null && args.length > 0 && args[0].length > col)
{
nargs = new int[args.length][args[0].length-1];
for(int i =0;i<args.length;i++)
{
int newColIdx = 0;
for(int j =0;j<args[i].length;j++)
{
if(j!=col)
{
nargs[i][newColIdx] = args[i][j];
newColIdx++;
}
}
}
}
}
public static void printArgs()
{
if(nargs != null)
{
for(int i =0;i<nargs.length;i++)
{
for(int j =0;j<nargs[i].length;j++)
{
System.out.print(nargs[i][j] + " ");
}
System.out.println();
}
}
}
Your difficulties are arising due to using variables outside of their scope. In java, variables basically only exist within the most immediate pair of braces from which they were declared. So, for example:
public class Foo {
int classVar; // classVar is visible by all code within this class
public void bar() {
classVar = classVar + 1; // you can read and modify (almost) all variables within your scope
int methodVar = 0; // methodVar is visible to all code within this method
if(methodVar == classVar) {
int ifVar = methodVar * classVar; // ifVar is visible to code within this if statement - but not inside any else or else if blocks
for(int i = 0; i < 100; i++) {
int iterationVar = 0; // iterationVar is created and set to 0 100 times during this loop.
// i is only initialized once, but is not visible outside the for loop
}
// at this point, methodVar and classVar are within scope,
// but ifVar, i, and iterationVar are not
}
public void shoo() {
classVar++; // shoo can see classVar, but no variables that were declared in foo - methodVar, ifVar, iterationVar
}
}
The problem you are having is because you are declaring a new 2-d array for each iteration of the for loop and writing one column to it, before throwing that away, creating a new array, and repeating the process.