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!
Related
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).
What I have done here is taken the contents of the table below and stored them in a list called tableElems
0 1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16 17
18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35
List<WebElement> tableElems = chrome.findElements(By.tagName("td"));
From this table I want to print in a pattern starting at the 4th element (#3 in the table) and I want to print 3 elements, then skip the next 6, print the next 3 and then skip the next 6, etc. etc.
So my expected output would be 3 4 5 12 13 14 21 22 23 30 31 32
My initial attempt ended with
for (int i = 3; i<tableElems.size(); i++) {
if(i % 3 == 0) { System.out.println(tableElems.get(i).getText()); }
else if(i % 4 == 0) { System.out.println(tableElems.get(i).getText()); }
else if(i % 5 == 0) { System.out.println(tableElems.get(i).getText()); }
}
Obviously this is wrong, because my % 3 will print the 9th element, % 4 will print the 16th element, etc.
I am having trouble wrapping my head around this, so any advice to point me in the right direction is appreciated!
try this:
for (int i = 3; i<tableElems.size(); i++) {
if (((i / 3) % 3) == 1) { System.out.println(tableElems.get(i).getText()); }
}
Think about this as dividing into groups of nine, and further dividing each group of 9 into groups of 3. on the second group of 3 (i.e. 3-5, 12-14) it will display.
int offset = 4;
int width = 3;
advice:
for each row in table check offset + width is under the row width, and then start from offset + 0, offset + 1 upto offset + width
and continue this loop for all the row of table
You mentioned that tableElems is a list, so I assume it's akin to a single-dimension array, rather than what appears to be a multi-dimensional table like you've laid out(I assume for visual purposes).
You're right by starting the for loop at i = 3. The easiest way, IMO, to do this is to just bump the loop ahead several spaces in the array after you've printed three elements. Here's my solution using C# and an array; you should be able to convert it to Java pretty easily.
int counter = 0;
for (int i = 3; i < array.Length; i++)
{
if (counter < 3)
{
Console.WriteLine(array[i]);
counter++;
}
else
{
i += 5; // we are incrementing by one on the next pass, so this can be 5
counter = 0;
}
}
If you want to stick to %, then this should work
int rowSize = 9;
for (int i = 0; i < tableElems.size(); i++) {
int column = i % rowSize;
if (column >=3 && column <= 5) {
System.out.println(tableElems.get(i).getText());
}
}
Update: Java code
for (int i = 3; i<tableElems.size(); i += 9) {
System.out.println(tableElems.get(i).getText());
System.out.println(tableElems.get(i+1).getText());
System.out.println(tableElems.get(i+2).getText());
System.out.println(tableElems.get(i+3).getText());
}
If you are creating a larger pattern:
int starting = 3;
int nextStartDistance = 9;
int waveCount = 3;
for (int i = starting; i<tableElems.size(); i += nextStartDistance) {
for (int b = 0; b <= waveCount; b ++) {
System.out.println(tableElems.get(i).getText());
}
}
This code is written in JavaScript, but the algorithm considered:
var list =[
0,1,2,3,4,5,6,7,8,
9,10,11,12,13,14,15,16,17,
18,19,20,21,22,23,24,25,26,
27,28,29,30,31,32,33,34,35];
for (var index = 3; index <= list.length; index +=9 ) {
var a = list[index];
var b = list[index+1];
var c = list[index+2];
var d = list[index+3];
console.log(a,b,c,d);
}
Result will be what you expected:
// 3 4 5 6
// 12 13 14 15
// 21 22 23 24
// 30 31 32 33
// user:~$
for (int i = 3; i < tableElems.size(); i += 9) {
for (int j = i; j < i + 3 && j < tableElems.size(); j++) {
System.out.println(tableElems.get(j).getText());
}
}
i think this would be very close to your code:
for (int i = 3; i < tableElems.size(); i++) {
if (i % 3 == 0) {
System.out.println(tableElems.get(i).getText());
} else if ((i % 3) == 1) {
System.out.println(tableElems.get(i).getText());
} else if ((i % 3) == 2) {
System.out.println(tableElems.get(i).getText());
i = i + 6;
}
}
i just adapted your modulo and skip 6 elements every time i hit the last one to print out
furthermore its quite effective because all unneeded elements are just skipped instead of iterated and checked
Assuming you only care about the values out of your table and the html structure is standard html tags as shown on your questions, then you can use css selector to select appropriate values.
chrome.findElements(By.cssSelector("td:nth-child(4),td:nth-child(5), td:nth-child(6)"))
Please note that css nth-child selector is 1 based.
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]);
}
}
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.
I just want to make sure if I am doing this correct. I am trying to count the number of operations performed for the worst case scenario in java
int sum = 0;
for (int i = 0; i < n; i++ )
sum++;
Is the number of operations 2+3n or 3+3n?
I got the answer from counting int sum = 0 and int i = 0 for the "2" and i < n, i++, and sum++ as the "3n". Or is it a 3 rather than a 2 because I have to count i < n before going through the loop?
But either way, is the theta characterization going to be Θ(n)?
Now what if there is a nested for loop like this:
int sum = 0;
for (int i = 0; i < n; i++ )
for (int a = 0; a < i; a++)
sum++;
would it be 3+n*(6a+2) = 6na+2n+3? with Θ(n^2)?
if i change the inner for loop from a < i to a < i*i, would the equation still hold as above or change?
Maybe it's easier to count the number of executions of each statement if there's only one per line:
int sum = 0; // 1 time
int i = 0; // 1 time
while (i < n) { // n+1 times
sum++; // n times
i++; // n times
}
Hence, T(n) = 3*n+3 = Θ(n).
int sum = 0; // 1 time
int i = 0; // 1 time
while (i < n) { // n+1 times
int a = 0; // n times
while (a < i) { // 1 + 2 + ... + n = n*(n+1)/2 times
sum++; // 0 + 1 + ... + n-1 = n*(n-1)/2 times
a++; // 0 + 1 + ... + n-1 = n*(n-1)/2 times
}
i++; // n times
}
Hence, T(n) = 3*n+3 + n*(n-1) + n*(n+1)/2 = Θ(n^2).
I would it count as 3+3n, because when n = 0 then you execute the following 3 commands:
int sum = 0;
int i = 0;
i < n
Now when n != 0 then you execute the declarations once (2) and for each execution of the loop each command once (3n) and the final comparison (which fails; 1). That makes 3+3n.
And yes, that would be Θ(n) (and O(n) and o(n)).
Yes, exactly. Look here for a mathematical definition.
It doesn't matter if you use 2+3n or 3+3n. You have lim_n->infty ( (3+3n)/n ) = 3 (both lim sup and lim inf are the same here). Because of that limites (which is greater 0 and not infinity), you know that is Big Theta n.
In your second example, you cannot use the inner-loop variables (a or i). The amount of sum++ operations:
When i == 0: zero sum++s are executed.
When i == 1: exactly one sum++ get's executed (when a==0).
When i == 2: 2 sum++s (a==0 and a==1)
When i == 3: 3 sum++s (a==0, a==1 and a==2)
...
When i == n-1: n-1 sum++s (a==0, a==1, ... and finally a==n-1)
That are all sum++s in your code. So let's sum them together:
0 + 1 + 2 + ... + n - 1
That is the same as (n-1)(n-2)/2.
I.e. we have Θ(n^2 + n). The same thing for a++ and a < i (well, one more to be exact but that doesn't matter). The amount of i++ ops is just n. So you end up with Θ(n^2).
It'll be 3+3n, because the comparison runs for each value of i from 0 to n inclusive. I'd says that's O(n).