I have 2 loops like this
goodexpressions and badexpressions are string arrays
for(int i =0; i < goodexpressions.length; i++) {}
&
for(int j =0; j < badexpressions.length; j++) {}
i'm trying to declare both of these in one loop, i've got this so far but it's not correct
for(int b = 0 , c = 0; b < goodexpressions.length; b++ c < badexpressions.length; c++)
what am I supposed to do to correct this statement?
Although what you are trying to do seems like a bad idea, here is a piece of code that will work. I don't know if it does exactly what you want it to though, since that isn't completely clear to me.
for(int b = 0, c = 0; b < goodexpressions.length || c < badexpressions.length; b++, c++) { }
When doing this, though, you still have to check if b and c are inside the array index range. You can also replace the || with && in which case you won't have to do that anymore, but you will be missing some items if the arrays are not equally long.
I think this will do what you are asking:
for (int b = 0, c = 0;
b < goodexpressions.length && c < badexpressions.length;
b++, c++)
Note that there are exactly 2 semicolons separators on an old-style for loop.
And based on your comment, I think this might be better:
for (int i = 0; i < Math.min(goodexpressions.length, badexpressions.length); i++)
Notes:
It is not at all clear what the loop body is going to do. That will determine the right way to combine the loops ... or if it is just a bad idea to combine them at all.
The above code is designed to stop at the smaller of the two lengths. If you want to stop at the larger, change && to || and min to max. However, if you do that, you also need to take care to avoid array bounds exceptions.
Unless the intent is to use both goodexpression[i] and badexpression[i] at the same time (e.g. compare them, combine them, and so on), your code will be more readable and more efficient if you use two separate loops.
Another possibility might be to simply check that the two arrays have the same length.
Depending on what you want to achieve, you should do one of the following. Say you have two lists A and B...
If you want to loop over all the elements in both lists A and B, create a new list, or array, holding the elements of both lists and loop over that list.
for (int i = 0; i < combinedAandB.length; i++) {
...
}
If you want to loop over all the combinations of elements from list A and list B, you have to use nested loops.
for (int i = 0; i < A.length; i++) {
for (int k = 0; k < B.length; k++) {
...
}
}
Update: Concerning the two-variable for-loop approach in your question and the other two answers: Note that since both those variables will take on exactly the same values in each iteration of the loop, you can just as well use just one variable:
for (int i = 0; i < goodexpressions.length || i < badexpressions.length; i++) { }
But also note that this will not do you any good in terms of avoiding code duplication, since you still have to everything to both, goodexpressions[i] and badexpressions[i]. A better approach might be to write a method holding the loop and calling that method once with goodexpressions and once with badexpressions.
Related
I update the values of a multi-dimensional array (Y[i][t][k]). Since the update needs to be done over many iterations, the runtime of this part of the code is really important. I was wondering if anyone knows how to do this in a more efficient way.
Below is the part that needs to be updated.
double [][][] Y=new double [a.length][b.length][c.length];
for(int i=0;i<a.length;i++){
for(int j=0;j<b;j++){
for (int k=0; k<c.length; k++){
if(i==w && j==r && k==u){// w, r and u can have any value.
Y[i][j][k]=g;
}else{
Y[i][j][k]=f;
}
}
}
}
Note that:
a is int [][].
b is int.
c is int [][].
q is double.
YIN is double [][][].
F is double.
g=q*YIN[i][j][k]+(1-q)*(Y[i][j][k]-F)
f=q*YIN[i][j][k]+(1-q)*(Y[j][j][k])
You are setting every element of a region of your multidimensional array, at a cost proportional to the number of elements set, so there's no reason to think that you can do it asymptotically better. However, it is likely that you can get some speed increase by using bulk-operation methods, and by handling the special case outside the loop instead of testing for it on every iteration. For example,
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
Arrays.fill(Y[i][j], 0, c.length, f);
}
}
if (c.length > 10) {
Y[0][0][10] = g;
}
Of course, this assumes that f is a constant expression, or at least that every evaluation of it is equal to every other (in the sense of the == operator) and produces no side effects. In that case, it is probably a bit better yet to engage bulk copying in place of bulk setting where you can do so:
for (int i = 0; i < a.length; i++) {
Arrays.fill(Y[i][0], 0, c.length, f);
for (int j = 1; j < b.length; j++) {
System.arraycopy(Y[i][0], 0, Y[i][j], 0, c.length);
}
}
if (c.length > 10) {
Y[0][0][10] = g;
}
If expression f does not satisfy the requirements above, then the best you can do might be just to lift the special case out of the loop, without changing anything else. For some expressions f and / or g, even that might not be possible, in the sense that it could produce an inequivalent result. For example, this would be the case where one or both are stateful in some relevant way, such as by closing over a counter.
As I understand from your code, your goal is to set Y[0][0][10] to g and other elements to f.
So how about forgetting about crazy loops and doing like the following code ?
Arrays.fill(Y, f);
Y[0][0][10] = g;
I'm looking for a way to use a flexible amount of for-loops or some solution that will do the same. Basically I want a variable to go from 0 to 100 in each loop and go through all combinations. The for-loops are nested so if I am looking for a solution for two agents I have:
for(int i = 0; i<=100; i++){
for(int j = 0; j<=100, j++){
//do some stuff with i and j
}
}
but I do not ex ante know how many agents will be needed so I'm looking for a flexible way to get the same result. This might be quite an easy question but I was not able to find a threat which gave me a working solution.
EDIT: It was pointed out to me that the question is not clear enough, I will try to demonstrate what I am trying to achieve:
Let's say I have n agents, if n == 1 then I would need this:
for(int j = 0; j<=100, j++){
//do some stuff with j
}
for n == 2 I would want:
for(int i = 0; i<=100; i++){
for(int j = 0; j<=100, j++){
//do some stuff with i and j
}
}
for n == 3 another for look around these existing ones and so on, but it need to be flexible as the user is asked for n and can type in any integer.
//EndEDIT I hope this made it clearer
Thank you in advance!
I think the easiest way to achieve this is recursively.
Assuming you want the same limits on each range (i.e. that i,j,k etc go from 0..100), you can do it like so:
void recursive(List<Integer> values, int depth) {
if (values.size() == depth) {
// Do the thing you want to do with the values, i.e. the "innermost loop".
} else {
// This is intentionally Integer, so that remove removes that value, not the element at that index.
for (Integer a = 0; a <= 100; ++a) {
values.add(a);
recursive(values, depth);
values.remove(a);
}
}
}
While there are fewer than depth values in the list, this adds each value in the range into the list in turn, and recurses.
Once there are enough values in the list, then it does the "thing" you want to do. The list will contain depth values, and you can access an individual value using values.get(i).
For example, if I have:
int Myarray[][] = new int[][] {{1,2}, {3,4}};
for (int line=0; line < Myarray.length; line++) {
for (int column = 0; column < Myarray[0].length; column++) {
// do something ...
}
}
How could I go through the entire array without the two loops?
Well you could use just a single loop:
for (int i = 0; i < Myarray.length*Myarray.length; i++) {
int row = i / Myarray.length;
int col = i % Myarray.length;
System.out.println(Myarray[row][col]);
}
But this assumes that your 2D array is square, i.e. its width and length are the same everywhere. Another way of saying this is that the 2D array is not jagged.
Demo
Note: As #Thilo mentioned above, this won't make things run faster. If you need to touch every element in your array, then my suggested code and your current double loop basically have the same complexity.
If you don’t need to know the line or column in the “do something” code (not stated in question), you could:
Arrays.stream(Myarray).flatMap(Arrays:stream)
.forEach(n -> /* do something with “n”, the cell value */);
You can iterate without any loops:
void recursive(int[][] array, int r, int c) {
if (r >= array.length) return;
if (c >= array[r].length) {
recursive(array, r+1, 0);
} else {
System.out.println(array[r][c]);
recursive(array, r, c+1);
}
}
Then invoke with recursive(array, 0, 0) to get started.
But there is no practical benefit in doing so. This would perform poorly, because of all the extra effort involved in calling a method vs just incrementing an int. (Plus, depending upon the size of the array, you could end up with a stack overflow).
I understand that new for each loop works with Iterable and arrays, but I don't know what goes behind the scenes when working with arrays.
Can anyone help me understand this? Thanks in advance.
int[] number = new int[10];
for(int i: number) {
}
The loop is equivalent to:
for(int j = 0; j < number.length; j++) {
int i = number[j];
...
}
where j is an internally generated reference that does not conflict with normal user identifiers.
A bit late, but here it is.
The compiler knows if you are using the for-each loop statement for a collection or for an array.
If used for collection,
the compiler translates the for-each loop to the equivalent for loop using an Iterator.
If used for an array,
the compiler translates the for-each loop to the equivalent for loop using an index variable.
Here is a description at oracle.com
In your code, you allocate an array of 10 integers in the memory and obtain a reference to it. In the for-loop you simply iterate over every item in the array, which initially will be 0 for all the items. The value of every item will be stored in the variable i declared in your for-loop as you iterate the array elements.
this is equivalent to:
for(int x = 0; x < number.length; x++) {
int i = number[x];
}
This is the equivalent to:
final int len = number.length;
for(int j = 0; j < len; j++) {
int i = number[j];
}
Note that the forEach will not evaluate the .length in each loop.
This might be also be eliminated by the JVM, but especially in case of collections,
where some would use
for(int j = 0; j < collection.size(); j++) {
it makes a (small) difference to the faster
int len = collection.size()
for(int j = 0; j < len; j++) {
The for each over arrays is essentially "sugar" over this construct:
for(int i = 0;i<number.length;i++)
{
}
I would imagine this was provided as a construct of the language so that people could use the enhanced for loop over a structure that was iterated over in the old way.
IntStream.range(1,4) can be used, if using java 8.
I am working on an assignment where I need to create two arrays, then look through them and create a new array that holds any values inside of both the first two. Originally, I was close to accomplishing this by making an arraylist but my lab professor told me that wasn't allowed so I needed to re-start and didn't have enough time to figure out the solution.
If you'd like to see the whole code I have now: http://pastebin.com/thsYnj2z
I am really struggling with this loop here:
for(int i = 0 ; i < Xarr.length ; i++){
for(int j = 0 ; j < Yarr.length ; j++)
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
k++;
System.out.println(ArrA[k]);
break;
}
My output is remaining 0 for my ArrA[k] array. I can't seem to trouble shoot this issue on my own.
try making these changes
for(int i = 0 ; i < Xarr.length ; i++){
for(int j = 0 ; j < Yarr.length ; j++)
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
System.out.println(ArrA[k]); // or print them all later
k++;
break; // break to outer loop
}
}
}
note
Assuming OP has correctly initialized ArrA
note2
Assuming that only unique values are required, hence the breaking
Does your solution require that no values are duplicated in ArrA? Or are duplicate values allowed? For example, if some values occur multiple times in each array, you could get multiple matches on the same number.
If duplicates aren't a problem:
for(int i = 0 ; i < Xarr.length ; i++){
for(int j = 0 ; j < Yarr.length ; j++){
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
System.out.println(ArrA[k]);
k++;
}
}}
As I understand it, the problem is to take 2 arrays, and produce a third array which is a Union of the first 2. Union of 2 sets being the subset of the values found in both sets.
Your code was missing some braces, so put those back in there. Also you wont want to print the k+1th item after you just put a value in ArrA[k] im assuming.
Otherwise you were pretty much there. The break terminates the inner loop and allows the outer loop to increment i and continue on. This is because you have already found a match, no need to continue searching, just move onto the next index in Xarr.
Algorithm goes like this: For each value in X, search Y for a match. If it is found, add this value to A.
for(int i = 0 ; i < Xarr.length ; i++) {
for(int j = 0 ; j < Yarr.length ; j++) {
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
System.out.println(ArrA[k]);
k++; //you probably want to increment k after you add to ArrA, not before
break;
}
}
}
public static void main(String... args){
int[] xArr = {1, 1,1,1,1,1};
int[] yArr = {1, };
int[] kArr = new int[xArr.length > yArr.length ? xArr.length : yArr.length];
int k = 0;
for(int x = 0; x < xArr.length; x++){
for(int y = 0; y < yArr.length; y ++){
int xNum = xArr[x];
int yNum = yArr[y];
if(xNum == yNum) kArr[k++] = xNum;
}
}
int[] resizedKArr = new int[k];
for(int i = 0; i < resizedKArr.length; i++) resizedKArr[i] = kArr[i];
Arrays.sort(resizedKArr);
for(int x : resizedKArr) System.out.println(x);
}
First, xArr and yArr are given some random numbers, and then kArr is initialized with the size of the lagest array we are comparing with to ensure the array has enough space to hold similar values.
Then, in the next section we do a loop inside of a loop to compare the values against each other and if they are similar then k++ and set the next value in the array. This goes on until the loops are completed, notice there really is never a need to break from either loop until all values are compared. At that point the loops break themselves and move on to the next bit of code.
The last section is just to create an array of the same size as k and move the values over, I don't know the requirements of your studies, although when using primitives like this you may want to do this in case you have a matching 0 as a number. Otherwise you'll have a ton of 0s filling the empty spaces of your array.
And lastly, we just sort the array for good measure and print it out.
Hope I've answered your question and you get something out of this post!
The problem is printing ArrA[k] after k++. Try increasing line after print.