Simplified, I basically have an if statement like this:
if(A[random]==1)
A[random]=0;
else
continue;
Now I know the 'continue' is for loop statements and this won't work, but I wanted something after the else that if indeed the else(basicaly the condition was false) was activated it repeated the first if(A[random]==1) statement.
You can use a while statement instead:
while (A[random] != 1) {
A[random] = 0;
// generate a new random...
}
You can try below recursion code and see if this resolve's your query
public class Test {
public void continueIf(){
if(A[random]==1)
A[random]=0;
else {
continueIf();
}
}
public static void main(String[] args) {
new Test().continueIf();
}
}
Please note if, if condition is not satisfy then it will lead to stackoverflowerror. That too it depends on the size of JVM memory. check this link for more details on stackoverflow error.
The if/Else statement won't work by itself with looping through an array. I suggest sticking it in either a For loop or a While loop. The loop will search the array and the if/else statement will check the index for the condition provided. I would also get rid of else too. You don't really need that part just the if.
A for loop in the most basic example would look something like this:
for(var i = 0; i < SIZE; i++)
{
if (A[i] == 1)
A[i] = 0;
}
SIZE would be the size of your array
random = ...; // get first random number
while (A[random] != 1) {
random = ...; // get new random number
}
A[random] = 0; // now is 1, switch it to 0
This should work.The other answers have described while and recursion so i am
also adding a do while loop.
do{
//generate the random number
}while(A[random]!=1)//The loop iterates till the condition A[random]!=1 is satisfied
A[random]==0;//changing the bit to 0
Please note that if there is no bit =1 in the array then this solution will fail because you are generating indexes randomly.
So if the array has no element =1 then it keeps on checking the indexes repeatedly and generates infinite loop.
Hope it helps.happy coding!!
Related
I am passing some parameters in the URL and then I add them in a list. My list has a limit of 5 elements. So if someone adds 6th element in the URL the list would simply ignore it. So I am trying to use a counter but the logic is not working as desired. I am using While loop to achieve this. So if list size is smaller than 5 set the agencyCds otherwise just return the list.
private List<IUiIntegrationDto> generateViewIntegrationReportData(ESignatureIntegrationConfig eSignConfig) throws Exception {
int counter = 1;
if(eSignConfig.getAdditionalAgencyCds() != null ) {
List<String> combinedAgencyCds = new ArrayList<String>();
for(String agencyCd : eSignConfig.getAgencyCd()) {
combinedAgencyCds.add(agencyCd);
}
StringTokenizer token = new StringTokenizer(eSignConfig.getAdditionalAgencyCds().toString(), StringConstants.COMMA);
while(token.hasMoreTokens()) {
combinedAgencyCds.add(token.nextToken());
}
while(combinedAgencyCds.size() < 5) {
counter = counter + 1;
eSignConfig.setAgencyCd(combinedAgencyCds);
}
// eSignConfig.setAgencyCd(combinedAgencyCds);
}
List<IUiIntegrationDto> intgList = getUiIntegrationManager().retrieveUiIntegrationReportData(eSignConfig.getAgencyCd(), eSignConfig.getCreatedDays(),
eSignConfig.getLob(), eSignConfig.getTransactionStatus(), eSignConfig.getAccounts(), eSignConfig.getSortKey(), eSignConfig.getSortOrder());
return intgList;
}
I am not completely sure about this logic if it is correct or if there is nay better approach.
Thanks
Try this instead of the last while in your code:
if(combinedAgencyCds.size() <= 5) {
eSignConfig.setAgencyCd(combinedAgencyCds);
} else {
eSignConfig.setAgencyCd(combinedAgencyCds.subList(0, 5));
}
The full combined list will then be used if it is less than 5 in size. Otherwise, only the first 5 elements are used.
Edit: Or even better:
eSignConfig.setAgencyCd(combinedAgencyCds.subList(0, Math.min(5, combinedAgencyCds.size())));
Ok so let's break down what your code is currently doing.
int counter = 1;
while(combinedAgencyCds.size() < 5) {
counter = counter + 1;
eSignConfig.setAgencyCd(combinedAgencyCds);
}
This snippet of code has a couple things wrong best I can tell. First, this loop has the possibility of running forever or not at all. Because combinedAgencyCds is never being manipulated, the size won't ever change and the logic being checked in the while loop never does anything. Second, there's a more efficient loop for doing this, assuming you don't need the counter variable outside of its usage in the while loop and that is using for loops.
Example syntax is as follows:
for (int i = 0; i < combinedAgencyCds.size(); i++) {
if (i < 5) {
// Do your logic here.
}
else {
break; // Or handle extra values however you want.
}
}
Notice there is no need for the explicit declaration for a counter variable as "i" counts for you.
Now in your actual logic in the loop, I'm not sure what the setAgencyCd method does, but if it simply sets a list variable in the eSignConfig like it appears to, repeating it over and over isn't going to do anything. From what I can see in your code, you are setting a variable with the same value 5 times. If you need any more explanation just let me know and I will be happy to revise the answer.
int a = 0;
int b = 0;
int c = 0;
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 6; i++) {
b = sc.nextInt();
a =+ b;
c =+ (a + 1);
if (c < 20) {
i = 2;
}
}
if I have lines numbered from 0 to 6 inside the loop, the loop would be
so if c is less than 20, it repeats the operation "c=+(a+1);" until it breaks out of the loop by c>=20.
this is a simplified code from my program, mine is GUI. every time I run the code, it freezes.
use c+= instead of c=+. try that, cheers!
and b+= instead ofb=+.
You can tag a loop and do break or continue instructions, but you need design the flow, it is not possible to go into specified line, because java don't use goto instruction. You can only switch the flow inside loops by those instructions.
myloopTag:
for (...; ...; ...) {
// and you can break current loop by:
break;
// or specific (outer) loop by
break myloopTag;
// you can also use 'continue' to go to the start of the loop and increment again
continue;
// or to 'continue' at a label:
continue myloopTag;
}
You're probably very new to the language. Welcome!
If I understand your description of your intent properly, you want your code to exit the loop when c>=20. Based on your description of numbering your lines and the fact that you have the statement:
if(c<20){
i=2;
}
it seems that you think that the iterator i in the for loop is related to the line that will be executed*. This is not the case. The iterator i is a variable that simply holds an integer (just like a, b, and c in your code).
I suggest you take a look at a tutorial on for loops. It might be helpful for you to review other language basics as well, like how control flow works (this may be a better one to start with, actually).
*This guess at your intent is further supported by you counting that there are 6 lines and that your loop goes up to 6.
This is a small part of my code. Here the break statement doesn't work. The if condition is executed but the break statement takes the control to the start of the while loop. "assign" and "clsAssign" are two array list. "clustersRefGlobal()" is a function and I don't want to pass "assign" when it is empty. However due to break not working it is called even when "assign" is empty. I am not sure why break statement doesn't stop the while loop
Wh:while (i < n) {
System.out.println("Start");
get = clustersRefGlobal(assign);
clsAssign.add(get.get(0));
assign = get.get(1);
if(assign.isEmpty()){
System.out.println("Inside");
break Wh;
}
System.out.println("End");
i++;
}
Here is the output
Start
End
Start
Inside
Start
Exception in thread "main" java.lang.NullPointerException
at softwareClustering.DominantSetClustering.clustersRefGlobal(DominantSetClustering.java:54)
at softwareClustering.DominantSetClustering.buildDominatSetClustering(DominantSetClustering.java:76)
at trees.PrototypeSelectionTree.clustersRefLocal(PrototypeSelectionTree.java:214)
at trees.PrototypeSelectionTree.clustersRefGlobal(PrototypeSelectionTree.java:180)
at trees.PrototypeSelectionTree.buildTree(PrototypeSelectionTree.java:59)
at trees.PrototypeSelectionTree.buildClassifier(PrototypeSelectionTree.java:235)
at weka.classifiers.Evaluation.crossValidateModel(Evaluation.java:617)
at trees.TestClassifier.main(TestClassifier.java:45)
Java Result: 1
The exception is because the "clustersRefLocal()" function is called with empty "assign" parameter. If any one knows whats the problem or what I am missing?
public double[] buildDominatSetClustering(int n) throws Exception {
int i = 1;
ArrayList<ArrayList<Integer>> clsAssign = new ArrayList<>();
ArrayList<Integer> assign = new ArrayList<>();
ArrayList<ArrayList<Integer>> get;
for (int j = 0; j < data.numInstances(); j++) {
assign.add(j);
}
Wh:
while (i < n) {
System.out.println("hello");
get = clustersRefGlobal(assign);
clsAssign.add(get.get(0));
assign = get.get(1);
if(assign.isEmpty()){
System.out.println("inside "+assign.size());
break Wh;
}
System.out.println(assign.size());
i++;
}
if(!assign.isEmpty())
clsAssign.add(assign);
double[] indexAssToClus = new double[data.numInstances()];
int count = 0;
for (ArrayList<Integer> a : clsAssign) {
for (int k = 0; k < a.size(); k++) {
indexAssToClus[a.get(k)] = count;
}
count++;
}
return indexAssToClus;
}
This is the function in which the code exist
The simple explanation to what you are seeing is that in fact the break is stopping the loop ... but the code around the snippet you have shown us is starting it again.
This will be apparent if you add a traceprint immediately before the labelled while statement.
The exception is because the "clustersRefLocal()" function is called with empty "assign" parameter.
I suspect that you are confusing "empty" with null. An empty string is a non-null String that has zero length. If you try to test if a null String is empty by calling String.isEmpty() you will get an NPE. The correct test for a non-null, non-empty String is this:
if (assign == null || assign.isEmpty()) {
// null or empty ... bail out
break;
}
I recommend you simply reverse the logic:
if(! assign.isEmpty()){
i++;
}
But failing that, check what is happening to your variable i:
Your check is for: while (i < n)
But the only place i is ever changed, it is incremented.
labeling your loops and using break label is discouraged. (its like the goto and causes spaghetti code.)
Besides, it's not making sense here, since you don't have nested loops. You can just change break Wh; to break;
I have an array with 5 size , and I want to assign value from random function if any index doesn't have it.
while(positionXtoStart==array1[0] || positionXtoStart==array1[1] ||
positionXtoStart==array1[2] || positionXtoStart==array1[3] ||
positionXtoStart==array1[4])
{
positionXtoStart = (rand1.nextInt(400) + 1)+30;
}
this solution is ok for small size of array but if i have array with size of 1000, I cant enter 1000 conditions in the while loop.
I tried For-loop with if-else condition in it but the
problem is, I want to check all array indexes at the same time.
Please try to understand what i am asking. I want to check all array index values at the same time (in one shot).
in For-loop, we can check only one value at a time.
If I understand correctly, you just need to loop through the array, checking each value.
for (int i = 0; i < array1.length; i++)
{
if (array1[i] == positionXtoStart)
{
positionXtoStart = (rand1.nextInt(400) + 1)+30;
break; // exit the loop
}
}
are you looking for something like this?
for(int i=0; i<array1.length; i++)
if(array[i] == whatever)
{
// do stuff
}
unfortunately, what you're asking is not possible. Even in your code:
while(positionXtoStart==array1[0] || positionXtoStart==array1[1] ||
positionXtoStart==array1[2] || positionXtoStart==array1[3] ||
positionXtoStart==array1[4])
the computer is checking one condition at a time. It's not doing all the conditions at once, like you may think it is. The code you posted is equivalent to the code #Supericy and #Samiam posted.
Unless there's a reason the forloops doesn't work for your case, I would say go with the answers that are posted here.
If you have to check each entry you have to go trough the whole array. An unordered array in not really suitable for searching trough it. Maybe you should think of changing your data structure into something like a BST so you have a guarantied O(logn) search.
To compare all elements in an unordered array you need linear time.
let say my code look like below
for(..)
for(..)
for(..){
break; //this will break out from the most inner loop OR all 3 iterated loops?
}
Your example will break out of the innermost loop only. However, using a labeled break statement, you can do this:
outer:
for(..)
for(..)
for(..){
break outer; //this will break out from all three loops
}
This will only break out from the inner loop. You can also define a scope to break out from. More from the language specs:
A break statement with no label
attempts to transfer control to the
innermost enclosing switch, while, do,
or for statement of the immediately
enclosing method or initializer block;
this statement, which is called the
break target, then immediately
completes normally.
Yes, without labels it will break only the most inner loop.
Instead of using labels you can put your loops in a seperated function and return from the function.
class Loop {
public void loopForXx() {
untilXx();
}
private void untilXx() {
for()
for()
for()
if(xx)
return;
}
}
From the most inner loop :)
int i,j,k;
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++)
for(k = 0; k < 2; k++)
{
printf("%d %d %d\n", i, j, k);
break;
}
Will produce :
0 0 0
0 1 0
1 0 0
1 1 0
You should take a look here: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/branch.html
as often mentioned i don't like to break with a label eather. so while in a for loop most of the time i'm adding a boolean varible to simple exit the loop.. (only if i want to break it of cause;))
boolean exit = false;
for (int i = 0; i < 10 && !exit; i++) {
for (int j = 0; j < 10 && !exit; j++) {
exit = true;
}
}
this is in my opinion more elegant than a break..
Many people here don't like labels and breaking. This technique can be compared to using a 'goto' statement, a flow control statement which allows jumping out of a block of code in a non-standard way, obliviating use of pre- and post conditions. Edsger Dijkstra published a famous article in Communications of the ACM, march 1968, 'Goto statement considered harmful' (it's a short read).
Using the same reasoning presented in the article, returning from inside an iteration as suggested by TimW is also bad practice. If one is strict, to create readable code, with predictable entry- and exit points, one should initialize the variable which will hold the return value (if any) at the beginning of the method and return only at the end of a mehod.
This poses a challenge when using an iteration to perform a lookup. To avoid using break or return one inevitably ends up with a while-loop with a regular stop condition and some boolean variable to indicate that the lookup has succeeded:
boolean targetFound = false;
int i = 0;
while (i < values.size() && ! targetFound ) {
if (values.get(i).equals(targetValue)) {
targetFound = true;
}
}
if (!targetFound) {
// handle lookup failure
}
Ok, this works, but it seems a bit clunky to me. First of all I have to introduce a boolean to detect lookup success. Secondly I have to explicitly check targetFound after the loop to handle lookup failure.
I sometimes use this solution, which I think is more concise and readable:
lookup: {
for(Value value : values) {
if (value.equals(targetValue)) {
break lookup;
}
}
// handle lookup failure here
}
I think breaking (no pun intended) the rule here results in better code.
it will breake from most inner loop,
if you want to break from all, you can hold a variable and change its value when you want to break, then control it at the beginning of each for loop