For loop inside other for loop - java

I have a String array like this:
one
twoo
three
four
five
six
seven
eight
nine
For each 3 elements, I want to create a new object setting fields of that object to the elements. For example:
one
twoo
three
would be used like:
obj.setOne("one");
obj.setTwoo("twoo");
obj.setThree("three");
I think that I have to use one for inside other but I donĀ“t know how.
I have tried like this but bad result:
ArrayList<MyClass> myobjects;
MyClass my_object = new MyClass();
for (int z = 0; z < myarray.size(); z++) {
for (z = 0; z < (z + 3) && z < myarray.size(); i++) {
if (i == 0) {
mipartido.setAttributeOne(datos.get(i));
}
else if (i == 1) {
mipartido.setAttributteTwoo(datos.get(i));
}
else if (i == 2) {
mipartido.setAttributeThree(datos.get(i));
}
myobjects.add(mipartido);
}
}

The simplest approach is to use one loop but iterate by 3:
for (int i = 0; i < myarray.size() - 2; i+=3) {
mipartido.setAttributeOne(myarray.get(i));
mipartido.setAttributeTwoo(myarray.get(i+1));
mipartido.setAttributeThree(myarray.get(i+2));
}
FYI: The English word for the number 2 is spelled "two".

You should try to only use one loop iterated by 3 if you're sure that myarray will always have a size equals to x*3.
MyClass mipartido;
for (z=0; z< myarray.size(); z+=3){
Then on the beginning of each iteration, you have to recreate a new mipartido object ( but declare it before the loop)
mipartido = new MyClass();
mipartido.setAttributeOne(datos.get(i));
mipartido.setAttributteTwoo(datos.get(i+1));
mipartido.setAttributeThree(datos.get(i+2));
myobjects.add(mipartido);
}
By using this, your ArrayList should be filled with 3 mipartido objects, all diferents.
But remember that your "myarray" size must be a multiple of 3.

I really like Bohemain's answer, but I wanted to suggest an alternative using the Modulus operator (that I think OP was going for in the original post).
for (int i = 0; i < myarray.size(); i++) {
switch (i % 3) {
case 0:
mipartido.setAttributeOne(myarray.get(i));
case 1:
mipartido.setAttributeTwo(myarray.get(i));
case 2:
mipartido.setAttributeThree(myarray.get(i));
}
}
You could do it this way such that your for loop still increments by one each time, but you alternate the method call. As explained here, the operator simply gets the remainder.
So as you increment, the switch statement will work like this:
0 % 3 = 0, 1 % 3 = 1, 2 % 3 = 2, 3 % 3 = 0, etc

Related

What's the easiest way to increment a value by x

I have a for loop with length 20.
I have a height of 800. I want to put a value 20 times separated by the same gap.
For example:
800 / 20 = 40
Every 40 I want to println the value. 40, 80, 120, 160... until 800.
I don't understand how to do this inside a loop. My approach is wrong and does not have the same gap between them.
for (int i = 0; i < array.size(); i++) {
int posY = (i != 0) ? 800/ i : 800;
println(posY);
}
you can use de Modulo Operador. more info
if(i % 40 == 0){
println(posY);
}
Math Explanation of Modulo here
Well there are imho three different aproaches. Which one depends on what else you need to do with i.
1) Use i directly:
for (int i = 40; i <= 800; i+=40) {
println(i);
}
This asumes that you don't need nothing else but the 20 numbers.
2) you need to count:
for (int i = 1; i <= 20; i++){
println(i*40);
}
2b) application eg. if 800 is in a variable:
for (int i = 1; i <= 800/40; i++){
println(i*40);
}
This assumes you need to track which step you are taking and want to do something with i.
3) you need the steps inbetween for something
for (int i = 1; i <= 800; i++) {
if(0 == i%40 ){ //if the rest of i/40 gives 0
println(i);
}
}
This last version prints the same numbers but still i goes over all values inbetween.
Plus if you have an array you need to iterate over:
replace the 800 with "array.length -1"
OR
replace the "<=" by "<" and use "array.length" above.
(And well there are a whole lot of variations of this)

How to find first instance of element array

I'm a pretty basic programmer and I'm coding a 'Master-mind' style guessing game program.
Now the part I'm stuck with is that I want to go through an array and increase the pointer when I come across a specific number.
Now thats pretty easy and stuff, but what I want to do is ONLY increase the counter if the number is encountered for the first time. So, for example if there are two numbers (189, 999), I want the counter to increase only once, instead of 3 times, which is what my code is doing. I know why its doing that, but I can't really figure out a way to NOT do it (except maybe declaring an array and putting all the repeated numbers in there and only incrementing it if none of the numbers match, but that's super inefficient) Here's my code:
for (int i = 0; i < mString.length(); i++) {
for (int j = 0; j < nString.length(); j++) {
if (mString.charAt(i) == nString.charAt(j)) {
correctNumbers++;
}
}
}
Thanks for taking the time to read! I'd prefer it if you wouldn't give me a direct answer and just point me in the right direction so I can learn better. Thanks again!
Your question is quite unclear. I suppose 989 and 999 will return 1. Because you only deal with number, so the solution is:
Create a boolean array with 9 element, from 0-9, named isChecked
Initialize it with false.
Whenever you found a matching number, say 9, turn the boolean element to true, so that you don't count it again (isChecked[9] = true).
Here is the code:
var isChecked = [];
function resetArray(input) {
for (var i = 0; i < 10; i++) {
input[i + ''] = false;
}
}
resetArray(isChecked);
var firstNumber = '989',
secondNumber = '999',
correctNumbers = 0,
fNum, sNum;
for (var i = 0; i < firstNumber.length; i++) {
fNum = firstNumber.charAt(i);
// Skip already checked numbers
if (isChecked[fNum]) {
continue;
}
for (var j = 0; j < secondNumber.length; j++) {
sNum = secondNumber.charAt(j);
if (fNum == sNum && !isChecked[sNum]) {
correctNumbers++;
isChecked[sNum] = true;
}
}
}
console.log(correctNumbers);
Tested on JSFiddle.
If you find anything unclear, feel free to ask me :)
(except maybe declaring an array and putting all the repeated numbers in there and only incrementing it if none of the numbers match, but that's super inefficient)
That approach is a good one, and can be made efficient by using a HashSet of Integers. Everytime you encounter a common digit, you do a contains on the set to check for that digit (gets in HashSets are of constant-time complexitiy - O(1), i.e. super quick), and if it's present in there already, you skip it. If not, you add it into the set, and increment your correctNumbers.
I believe this would help
int found=0; for (int i = 0; i < mString.length(); i++) {
for (int j = 0; j < nString.length(); j++) {
if (mString.charAt(i) == nString.charAt(j)) {
if(found==0){
correctNumbers++;
}
}
}
}
You could try making another 1D array of
int size = nstring.length() * mstring.length();
bool[] array = new bool[size];`
and then have that store a boolean flag of whether that cell has been updated before.
you would find the unique index of the cell by using
bool flag = false
flag = array[(i % mString.length()) + j)];
if(flag == true){
<don't increment>
}else{
<increment>
array[(i % mString.length()) + j)] = true;
}
you could also do this using a 2d array that basically would act as a mirror of your existing table:
bool[][] array = new bool[mstring.length()][nString.length()];
Why not just use the new stream api? Then it's just that:
Arrays.stream(mString).flatMapToInt(s -> s.chars()).distinct().count();
I'll explain:
Arrays.stream(mString) -> Create stream of all strings.
flatMapToInt -> create single concatenated stream from many IntStreams
s -> s.chars() -> Used above to create streams of characters (as ints)
distinct -> remove all duplicates, so each character is counted only once
count -> count the (unique) characters

Loop for grabbing certain char's in a string

If I have a string and an int, I want to be able to create a loop that will print the first char of the string, followed by each the char at value of that int.
e.g. If I have the word "Miracle" and the int 2, the result should be "Mrce". My code does this, but stops a char short for certain words.
System.out.println(str.charAt(0));
while (n <= str.length())
{
System.out.println(str.charAt(n));
n = n+n;
}
This works for strings like "abcdefg" and int 3. It prints "adg", but if the string is "miracle" and int 2, it prints "mrc" and not "mrce".
I'm pretty sure the problem is in the "n= n+n" statement.
Because if the int is 3 and the string is greater than 3 it will loop, but in the n=n+n statement it will loop enough that n will be greater than str length and it halts.
How can I correct this?
You are right, your problem is with n=n+n because it multiple n with 2 in every step so you must change that.
change your code like this :
int m = 0;
while (m < str.length())
{
System.out.println(str.charAt(m));
m = m+n;
}
n = n+n; means that in each iteration you are multiplying your n by 2, so
iteration | n
----------+-------
1 | 3
2 | 3+3=6
3 | 6+6=12
and so on.
What you need is temporary variable (iterator) which will use n but will not change it.
Generally more readable way to write it would be with for loop like
for (int i = 0; i < str.length(); i = i+n){//or `i += n`
^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^
// start at continue when in next step
System.out.print(str.charAt(i));
}
I'll answer with a counterquestion: where is this mentionned int? What walue should it have, and what value does it have?
In short, you should have one variable which has the step value and another variable which acts as a cursor.
Something like
int cursor = 0;
while (cursor <= str.length()) {
System.out.println(str.charAt(cursor));
cursor += stepValue;
}
Here you see that it is necessary to have two distinct variables here.
It is working for first few instances as 2+ 2 = 4, but after that - its doing 4 + 4 = 8, while you need is 4 + 2 = 6.
Take a new var (v), assign it the initial value, & instead of doing n = n + n, do
n = n + v
I think this is what you need
int n = 0;
int skip = 2;
while (n < str.length())
{
System.out.println(str.charAt(n));
n+=skip;
}
First of all, you have an error here:
n <= str.length()
It should be
n < str.length()
because strings are indexed from 0 to length-1.
Also make sure you are indexing from 0, not from 1.
Another thing is that you are adding a bigger number each time. So yes - you are right about n+n - it's wrong.
You should do something like this:
n = ...;
for (int i = 0; n * i < str.length(); ++i)
{
int index = n * i;
System.out.println(str.charAt());
}
This way you have n * 0, n * 1, n * 2, ..., which is what you want.
There are two things wrong in your code:
If n == str.length(), it will throw an exception, as it tries to
access str.charAt(n), which in that case doesn't exist.
Another thing, n = n + n will change the value of n every time, so you
will add a bigger number every time instead of the same.
You could use a for-loop for a cleaner approach though:
for (int i = 0; i < str.length(); i += n) {
System.out.println(str.charAt(i));
}

Need help reducing triple for loop to increase efficiency

for (int i = 0; i < 3; ++i) {
for (int k = 0; k < 7; ++k) {
for (int h = i; h < 4 + i; ++h) {
result = state.getAt(k, h);
if (result == 1) {
++firstpl;
}
if (result == 2) {
++secondpl;
}
if (firstpl > 0 && secondpl > 0) {
break;
}
//y = k;
}
if (firstpl == 0 && secondpl == 0) {
break;
} else if (firstpl > secondpl) {
score += firstpl * firstpl;
//if(state.getHeightAt(y)-3 < 3) score += 3+firstpl*2;
} else {
score -= secondpl * secondpl;
//if(state.getHeightAt(y)-3 < 3) score -= 3+secondpl*2;
}
firstpl = 0;
secondpl = 0;
}
}
basically I have a 7 by 6 grid. I am going through 7 columns and looking at every 4 consecutive blocks vertically. Since there is 6 blocks upward. There is 3 four consecutive block for each column. State.getAt(k,h) takes in a x and y and returns a value.
I don't think you can improve on this, unless you can figure out an alternative representation for this "state" that allows this computation to be performed incrementally.
And since you have failed to properly explained what the state or the calculation actually mean, it is difficult for anyone but you to figure out whether an alternative approach is even feasible. (And I for one am not going to attempt to reverse engineer the meaning from your code.)
OK. For Connect4, the win / lose is a line of 4 checkers horizontally, vertically or diagonally in the 7x6 grid. So what you could do is represent the score-state as an array of counters, corresponding to each of the columns, rows and diagonals in which a winning line could be made. (7 + 5 + 4 + 4 = 20 of them => 20 counters) Then construct a static mapping from an (x,y) position to the indexes of lines that pass through that. When you add a checker at point (x,y) you look up the counters and increment them. When you remove a checker ... decrement.
I'm not sure how that relates to your existing scoring function ... but then I don't see how that function relates to a strategy that would win the game. Either way, you could potentially use the approach above to calculate scores incrementally.

Adding elements to last array position

Im trying to add an element to an array at its last position in Java, but I am not able to...
Or rather, I don't know how to. This is the code at the moment:
String[] values = split(line, ",");
int[][] coordinates = new int[2][values/2];
for(int i = 0; i < values.length; i++) {
if(i % 2 == 0) { //THIS IS EVEN VALUES AND 0
coordinates[0][coordinates[0].length] = values[i];
} else { //THIS IS ODD VALUE
coordinates[1][coordinates[1].length] = values[i];
}
}
EDITED VERSION:
String[] values = split(line, ",");
int[][] coordinates = new int[2][values/2];
int x_pos = 0;
int y_post = 0;
for(int i = 0; i < values.length; i++) {
if(i % 2 == 0) { //THIS IS EVEN VALUES AND 0
coordinates[0][x_pos] = values[i];
x_pos++;
} else { //THIS IS ODD VALUE
coordinates[1][y_pos] = values[i];
y_pos++;
}
}
values is being read from a CSV file. My code is I believe wrong, since it will try to add the values always at the maximum array size for coordinates[] in both cases.
How would I go around adding them at the last set position?
Thanks!
/e: Would the EDITED VERSION be correct?
Your original code has two problems:
it addresses the array badly, the las element in a Java array is at position length-1, and this would result in an ArrayOutOfBoundsException
even if you'd correct it by subtracting 1, you would always overwrite the last element only, as the length of a Java array is not related to how many elements it contains, but how many elements it was initialised to contain.
Instead of:
coordinates[0][coordinates[0].length] = values[i];
You could use:
coordinates[0][(int)Math.round(i/2.0)] = values[i];
(and of course, same with coordinates[1]...)
EDIT
This is ugly of course:
(int)Math.round(i/2.0)
but the solution I'd use is far less easy to understand:
i>>1
This is a right shift operator, exactly the kind of thing needed here, and is quicker than every other approach...
Conclusion: this is to be used in a live scenario:
Use
coordinates[0][i>>1] = values[i];
EDIT2
One learns new things every day...
This is just as good, maybe a bit slower.
coordinates[0][i/2] = values[i];
If you know you'll definitely have an even number of values you can do
for(int i = 0; i < values.length / 2; i++) {
coordinates[0][i] = values[2*i];
coordinates[1][i] = values[2*i + 1];
}
You have to store the last position somewhere. .length gives you the size of the array.
The position in the array will always be the half of i (since you put half of the elements in one array and the other half in the other).
String[] values = split(line, ",");
int[][] coordinates = new int[2][values/2];
for(int i = 0; i < values.length; i++) {
if(i % 2 == 0) { //THIS IS EVEN VALUES AND 0
coordinates[0][ i / 2] = values[i];
} else { //THIS IS ODD VALUE
coordinates[1][ i / 2 + 1 ] = values[i];
}
}
The array index for java is from "0" to "array length - 1".
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Each item in an array is called an element, and each element is accessed by its numerical index. As shown in the above illustration, numbering begins with 0. The 9th element, for example, would therefore be accessed at index 8.
why not:
String[] values = split(line, ",");
int[][] coordinates = new int[2][values/2];
for(int i = 0; i < values.length; i+=2) {
coordinates[0][i/2] = values[i];
coordinates[1][i/2] = values[i+1];
}

Categories

Resources