Perform action after certain number of loops in java - java

I have to show a message in the console after reaching a specific number of loops in an array list (e.g. 10) and then display a message about the remaining items in the array list.
The array list contains all the lowercase letters from a to z.
Now, in a counter, I have used MOD to check that
for (int i = 0; i > arrayList.length; i++)
{
// If loop is not at 0 and MOD with 10 is == 0 then it means we have to show message
if(i != 0 and i % 10 == 0)
{
// Show console
}
}
How do I handle the remaining items? Since there are 26 letters in the alphabet, it will print on first 20 but I'm not sure how to deal with the last six. The message should be printed on that too. It should show a console message 3 times not 2.

Simple Change is to check again if the array end is reached .
for (int i = 0; i < arrayList.length; i++)
{
// If loop is not at 0 and MOD with 10 is == 0 then it means we have to show message
if((i != 0 and i % 10 == 0) || (i == arrayList.length - 1))
{ // This executes on 10 , 20, and end of array.
// Show console
}
}

Since there is 26 in your list, you could break it up more evenly and on the last value.
for (int i = 0; i < arrayList.length; i++) {
// do something
// every ~1/3rd completed
if(i % 9 == 8 || i == arrayList.length - 1) {
// Show console
}
}

You can simply add an additional condition, that checks if the message was shown thrice. If the message was not shown thrice, the third message will be shown on the last element of the array.
This could work for arrays with elements greater than 20 elements.
int count = 0;
for (int i = 0; i > arrayList.length; i++)
{
// If loop is not at 0 and MOD with 10 is == 0 then it means we have to show message
if((i != 0 and i % 10 == 0) or (count<3 and i = arrayList.length-1))
{
count++;
// Show console
}
}

Related

Find the longest repeating sequence

there is such a question. I have a method that reads the bytes from a file into an array, and the method that searches for the longest byte sequence in this array.
private int element;
private int lastElement;
private int length;
private byte[] readByteFromFile(File name) throws IOException {
return Files.readAllBytes(name.toPath());
}
private void searchByte(byte[] byteMass) {
for (int i = 0; i < byteMass.length; i++) {
int count = 0;
for (int j = i + 1; j < byteMass.length; j++) {
if (byteMass[i + count] == byteMass[j]) {
if (count >= length) {
length = count + 1;
element = i;
lastElement = j - count;
}
count++;
} else {
count = 0;
}
}
}
}
Suppose that my file contains such a sequence of numbers:
444478126354444
In the case of processing, my method will deduce that the first occurrence was at 0, and the second at 11 and length of sequence = 4
But if I have such a sequence
133333444478126354444
Then my method will deduce that the first occurrence was at 1, and the second at 2, and the length of the sequence 4
How it can be fixed, that the method to continue to work correctly?
It is not tested. Don't have IDE infront of me.
The changes from the original code are. The second loop iterates one element less. If the next element is not equel to the previous then the loop exits.
private void searchByte(byte[] byteMass) {
int maxLength = 0
int element;
for (int i = 0; i < byteMass.length; i++) {
int count = 0;
for (int j = i + 1; j < byteMass.length-1; j++) {
if (byteMass[i] == byteMass[j]) {
if (count > length) {
maxLength = count;
element = i;
}
count++;
} else {
break;
}
}
}
If you haven't already I think it's very important to trace out the logic of your code!!! It's really important that you attempt to do this before asking for help. If you rely on others to work out your own logic, you won't make much progress as a programmer.
That being said, let's dive in and follow your code when it runs with the problem input (this isn't actual code, we're just looking at the values as the program runs)
byteMass = 133333444478126354444
(byteMass.length = 21)
length = 0
0 (i) < 21 (byteMass.length): true
count = 0
1 (j) < 21: true
1 (byteMass[0 (i + count)]) == 3 (byteMass[1 (j)]): false
count = 0
2 (j) < 21: true
1 (byteMass[0 (i + count)]) == 3 (byteMass[2 (j)]): false
count = 0
3 (j) < 21: true
1 == 3: false
it continues on like this, but something interesting happens when j = 12
12 (j) < 21: true
1 (byteMass[0 (i + count)]) == 1 (byteMass[12 (j)]): true
0 (count) >= 0 (length): true
length = 1 (count + 1)
element = 0 (i)
lastElement = 12 (j - count)
count = 1
This, to me at least, looks like unexpected behavior! We want to count repeated numbers, but this 1 is 11 digits away from the previous 1! We can fix this by editing the inner for loop like this
for (int j = i + 1; j < byteMass.length && byteMass[i] == byteMass[j]; j++) {
This way, the inner loop breaks as soon as byteMass[i] == byteMass[j] evaluates to false. now let's restart our process with the new inner for loop
byteMass = 133333444478126354444
(byteMass.length = 21)
length = 0
0 (i) < 21 (byteMass.length): true
count = 0
1 (j) < 21 && 1 (byteMass[0 (i)]) == 3 (byteMass[1 (j)]): false
1 (i) < 21: true
count = 0
2 (j) < 21 && 3 (byteMass[1 (i)]) == 3 (byteMass[2 (j)]): true
0 (count) >= 0 (length): true
length = 1 (0 (count) + 1)
element = 1 (i)
lastElement = 2 (2 (j) - 0 (count))
count = 1 (0 (count) + 1)
3 (j) < 21 && 3 (byteMass[2 (1 (i) + 1 (count))]) == 3 (byteMass[3 (j)]): true
1 (count) >= 1 (length): true
length = 2 (1 (count) + 1)
element = 1 (i)
lastElement = 2 (3 (j) - 1 (count))
This seems like unexpected behavior to me, but I won't fix it because I don't know how: I have no idea what element and lastElement represent. The code continues on like this until j = 6:
6 (j) < 21 && 3 (byteMass[5 (1 (i) + 4 (count))]) == 4 (bteMass[3 (j)]): false
2 (i) < 21: true
count = 0
3 (j) < 21: true
3 (byteMass[2 (2 (i) + 0 (count))]) == 3 (byteMass[3 (j)]): true
length = 1 (0 (count) + 1)
element = 2 (i)
lastElement = 3 (3 (j) - 1 (count))
count = 1 (0 (count) + 1)
This once again continues in the same fashion until j = 6. At this point hopefully you can see why your program isn't working as expected. But I still haven't answered the question of how to fix it. I don't really understand your thought process on how to solve this problem but I'll share with you my own
First of all we need to break the problem into smaller chunks!
You can do that any way you want to but here's my way: Our goal is to find the longest repeated pattern. Well in order to do that we need to figure out
when a number repeats itself and how many times it repeats itself
if that specific number repeated itself that specific amount of times anywhere else in the sequence. If it does, we'll need to save the amount of times it repeats itself
Then we'll repeat the process but only save the data if the number of repeats is larger than the saved data
It's actually a kind of complex problem and will probably be easier to solve with helper functions to be honest. I hope this helps!

segregate list elements with different groups in java

Suppose I have one list which always has the count of even number. Now I want to segregate the list with different group indexes with below conditions,
1) First element (1st element) with one index (EX: 1)
2) Next two elements with same index (Ex: 2nd, 3rd element with index 2,
4th and 5th element with index 3)
3) Last element(6th element) with index 4
I tried with nested for loops to achieve the same, but didn't get the expected output.
Any help is appreciated.
Sample Input:
[2,3,53,52,33,12,44,66]
Sample Output:
2 - 1
3 - 2
53 - 2
52 - 3
33 - 3
12 - 4
44 - 4
66 - 5
I have implemented this using the two additional variables z and count, I am
incrementing z only if the count%2 is 0, and at-last we need to check if the
size-1 is equal to the i variable for the third condition.
Also, for the first condition I am printing the arraylist value at first index and z variable value at i iff the i counter value is 0.
Please see the below code that I have simulated for your input list that I
have added manually ! Please use the link to test :
http://rextester.com/ESYF23501
import javafx.collections.ArrayChangeListener;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> a= new ArrayList<Integer>();
a.add(2);
a.add(3);
a.add(53);
a.add(52);
a.add(33);
a.add(12);
a.add(44);
a.add(66);
int i = 0;
int z = 2;
//Count to group the middle number by checking its value with respect to mod 2
int count = 0;
for(i = 0; i < a.size(); i++)
{
if(i == 0 )
{
z = i+1;
System.out.println(""+a.get(i)+" " + "" +z+"" );
}
if(i > 0 && i != (a.size() -1))
{
//Increament z if the count is even so that we print the group for two times
if(count%2 == 0)
{
z++;
}
System.out.println(""+a.get(i)+"" +" "+ ""+z+"" );
count ++;
}
if(i == a.size() -1 )
{
z++;
System.out.println(""+a.get(i)+"" +" "+ ""+z+"" );
}
}
}
}
This should work correctly if I understood your question right:
System.out.println(elements.get(0) + " - 1"); // Prints the first number, which has the value of 1
int value = 2; // Value corresponding to the number
for (int i = 1; i < elements.size(); i++) { // Loops through the list starting at second element (index of 1)
System.out.println(elements.get(i) + " - " + value); // Prints the number and the value
if (i % 2 == 0) value++; // Increases the value every two loops
}
It starts by printing out the first number and 1, which as you described always corresponds to each other. Then it loops through the list of numbers starting at the second number (i = 1), and prints out each number and the corresponding value. The value increases every two loops, which is every time the loop number is divisible by 2 (i % 2).

Replacing Multiples of numbers in Fibonacci series using Flag method

As the title suggests, I have code for a Fibonacci series and my goal is to replace multiples of numbers (3, 5, 7 and combinations of them) in the series with a word. I was suggested to use a flag in my if loop to check for the printed phrase, and if the phrase is printed, to skip that number. Essentially, what I want the output to look like is:
1 1 2 skip 8 13 skip 34 55
(this is replacing multiple of three only, for now).
Instead, what I am getting is:
1 1 2 3 skip5 8 13 21 skip34 55
Here is my code as of now:
int febCount = 50;
long[] feb = new long[febCount];
feb[0] = 1;
feb[1] = 1;
for (int i = 2; i < febCount; i++) {
feb[i] = feb[i - 1] + feb[i - 2];
}
for (int i = 0; i < febCount; i++) {
System.out.print(feb[i] + ((i % 10 == 9) ? "\n" : " "));
if (feb[i] % 3 == 0)
System.out.print("skip");
}
Any and all help is appreciated!
Let's walk through the code you have provided and attempt to understand why it's not working.
//The first thing we do is setup the loop to iterate through the fib numbers.
//This looks good.
for (int i = 0; i < febCount; i++) {
//Here we print out the fibonacci number we are on, unconditionally.
//This means that every fibonacci number will be printed no matter what number it is
//we don't want that.
System.out.print(feb[i] + ((i % 10 == 9) ? "\n" : " "));
//After we print the number, we check to see if it is a multiple of three.
//maybe we should be waiting to print until then?
if (feb[i] % 3 == 0)
System.out.print("skip");
}
Now that we have walked through the code, we can propose a new solution.
Let's try updating the loop so that it wait's to print the fibonacci number until AFTER we've checked to see if it meets our conditions.
for (int i = 0; i < febCount; i++) {
if (feb[i] % 3 == 0 || feb[i] % 5 == 0 || feb[i] % 7 == 0) { //check if multiple of 3 5 or 7
System.out.println(" Skip ");
} else { //if it's not a multiple, then print the number
System.out.println(" " + feb[i]);
}
}

issue with for loops in 2D array program

Okay so my current assignment has me making a program that can mimic percolation, meaning that it has to read an array, where 1 means the space is closed, 0 means the space is open. Next, it must change all the 0's at the top row of the array to 2's representing the liquid being poured in. The liquid can then follow the 0's (representing the flow), changing them all to twos along the way. Liquid can move up, down, left, and right. not diagonal. I have my program almost working, but the for loops don't seem to go through more than the first row of the array.
public class Percolation2 {
public static void main (String[] args) {
int[][] filter1 = {{1,0,1,0,1,1,0},
{1,0,1,1,1,0,0},
{0,0,0,1,0,0,1},
{1,1,0,1,1,1,1},
{1,0,0,1,1,0,1},
{1,0,1,0,1,0,1},
{0,0,0,0,1,1,0},
{1,1,1,0,1,0,1}};
for(int i=0; i<7; i++) {
if(filter1[0][i] ==0) {
filter1[0][i] = 2;
}
}
for ( int i = 0 ; i < filter1.length ; i++ ) {
for ( int j = 0 ; j < filter1[i].length ; j++ ) {
if ( filter1[i][j] == 0 )
if(i-1 > 0 && filter1[i-1][j] == 2)
filter1[i][j] = 2;
if(i+1 < 7 && filter1[i+1][j] ==2)
filter1[i][j] = 2;
if(j-1 > 0 && filter1[i][j-1]==2)
filter1[i][j] = 2;
if(j+1 < 7 && filter1[i][j+1] == 2)
filter1[i][j] = 2;
}
}
for(int i = 0; i < filter1.length; i++) {
for(int j = 0; j < filter1[i].length; j++) {
System.out.print(filter1[i][j]);
if(j < filter1[i].length - 1) System.out.print(" ");
}
System.out.println();
}
}
}
My output is as follows:
2 2 2 2 2 2 2
1 0 1 1 1 0 0
0 0 0 1 0 0 1
1 1 0 1 1 1 1
1 0 0 1 1 0 1
1 0 1 0 1 0 1
0 0 0 0 1 1 0
1 1 1 0 1 0 1
So you can clearly tell that it is not looping properly.
Each turn the liquid can move one level. Your for statements are correct, all elements of the array are visited. You need another loop for the proper amount of turns.
I don't want to give you the answer directly as there is a lesson to be learned here, you need to have something like:
//Init
boolean done = false;
while(!done) {
for (int i = 0; i < filter1.length; i++) {
for(int j = 0; j < filter1[i].length; j++) {
if(filter1[i][j] == 0)
....
}
}
//add the print matrix code here if you want it done after each turn.
done = amIDone();
}
Overall your code is structured pretty poorly. You should make use of constants for the array lengths, and you could also define methods for your two doubly nested for loops. At the bare mininum, I would have a printMatrix() method.
I see a couple problems here:
1) You seemed to have left out curly brackets around the block of code following if(filter1[i][j] == 0) in your double for loop.
2) Below that, your check for out-of-bounds is incorrect if(i-1 > 0 && ... should be if(i-1 >= 0 && .... And, if(j+1 < 7 && ... should be if(j+1 < 8 && ...
3) In your question you say that your output is 2 2 2 2 2 2 2 ... . But your code produces different results, your output should be 1 2 1 2 1 1 2 .... Thats what I get when I run for(int i=0; i<7; i++) { if(filter1[0][i] == 0) { filter1[0][i] = 2; } }
4) Pete hints at the problem. But more specifically, you are doing one pass down the matrix (2D array). There is no ability to go up with the liquid (nor left).
Lets call these items cells. And when a cell gets liquid (a.k.a. it turns to == 2), it should percolate that liquid to the neighboring cells which are empty (a.k.a. set to 0). This sounds like a call for recursion, IMHO!
Once you fix the first three issues. Put the payload of your double for loop into a recursive function such as this here:
public void percolate(int x, int y) {
if ( filter1[x][y] == 0 ) {
if(x-1 >= 0 && filter1[x-1][y] == 2) filter1[x][y] = 2;
if(x+1 < 7 && filter1[x+1][y] == 2) filter1[x][y] = 2;
if(y-1 >= 0 && filter1[x][y-1] == 2) filter1[x][y] = 2;
if(y+1 < 8 && filter1[x][y+1] == 2) filter1[x][y] = 2;
if ( filter1[x][y] == 2 ) {
if ( x-1 >= 0 ) percolate(x-1,y);
if ( x+1 < 7 ) percolate(x+1,y);
if ( y-1 >= 0 ) percolate(x,y-1);
if ( y+1 < 8 ) percolate(x,y+1);
}
}
}
Then just call it for each cell in your double for loop. Actually, since the liquid starts at the top, I guess you could just call this percolate for each cell in the second row, only. It will percolate down and round from there.
As you might can see, this is not the most efficient solution, it double/triple checks for percolation on some cells. But this is the slim, nuts and bolts version.
EDIT: Fixed typeos, got rid of unnecessary boolean.

"If statement" continuously checking for multiples of for loop's index count

I have a for loop that checks for every 5th position. And at every 5th position, I'm performing an action like so (which works):
for(int i = 0; i < foo().length; i++)
{
System.out.print(i);
if(i == 5 || i == 10 || i == 15)
System.out.println();
}
Is there a way to write if statement so no matter how long foo().length is, I don't have to keep coming back to adjust it?
Use modulus(%) operator: -
if (i % 5 == 0) {
}
5 % 5 == 0, 10 % 5 == 0, ...
Since you are using a for loop, you can simply change your increment from i++ to i += 5, and leave the if condition.
for (int i = 0; i < someNum; i += 5) {
// No need to check for `i` against `modulus 5`.
}
You can use next for witout if statement
for(int i = 0; i < foo().length; i+=5)
{
adding 5 to i step by step
Use the following:
if ( i % 5 == 0 )
if you want to put it in a single print statement this would work too.
for(int i = 0; i < foo().length; i++)
{
System.out.printf("%d%s", i, (i%5==0) ? "\n" : "");
}

Categories