I was wondering if I could write this very thing but with one single loop, instead of two?
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[0].length; col++) {
if ((row + col) % 2 == 0) {
System.out.print(matrix[row][col] + ", ");
sum += matrix[row][col];
}
}
System.out.println("with a sum of " + sum);
}
Actually just ignore the body of the loop.. It's totally irrelevant, I have no idea whatsoever why I included it.. How to somehow combine the two for loops is my question.
Just keep it simple, if possible. Thank you!
You can, though it's inefficient:
for(int i = 0 ; i < matrix.length * matrix[0].length ; i++)
sum += matrix[i % matrix.length][i / matrix.length];
The basic idea would be to map each index to a value in a 2d-number space, using the fact that we know the length of each "row" of the array (matrix.length). We can compose a single index, that uniquely identifies two indices matrix[x][y], by z = x + y * matrix.length. The reverse of this would then be:
x = z % matrix.length
y = z / matrix.length
This depiction would be complete, e.g. each z in [0 , matrix.length * matrix[0].length) would identify exactly one pair of indices, thus we can use it here.
Paul's answer is initially how I thought to do it. But there is the slight restriction that you need to have a rectangular two-dimensional array (i.e. the sub-arrays are all the same length). If you're modelling a "matrix", this is likely to be the case, but more generally you may want to sum up non-rectangular arrays.
A way around this is to do something like this:
for (int r = 0, c = 0; r < matrix.length;) {
if (c < matrix[r].length) {
sum += matrix[r][c];
++c;
} else {
c = 0;
++r;
}
}
Although it's getting a bit messy. I'd just go for a nested loop instead.
Related
Jump Encrypt: prompt the user to enter an integer (jump value) that is between 2 and the square root of the length of the current message, inclusive. Now imagine that we are going to write the current message in a table form, using the same number of rows as the jump value. The character order in the original message would be the order of the
first column, followed by the second column, etc. For example, with jump value of 5, the original message would be in table form:
T i e g a
h s i m g
i o n e e
s t r a s .
h i l s
To complete the encryption, display the encrypted message row by row, "Tieg ahs imgi oneestras. hils" for the above. Hint: this can be accomplished in one step with nested loops! No arrays or actual tables are required in the solution,
So I have attached the code that I have used down below, but it seems to be that I am off by one column when it comes to printing the message.
public static String jumpEncrypt(String message, int jumpValue) {
String jencrypt = "";
for (int i = 0; i < jumpValue; i++) {
for (int j = 0; j < (jumpValue); j++) {
jencrypt += message.charAt(i + j*jumpValue);
}
}
return jencrypt;
}
The expected output for the original message with a jumpValue of 5 should be "Tieg ahs imgi oneestras. hils" but I am getting an output of "Tieg hs imi onestras hils"
You are iterating both i and j up to the jumpValue. That means that the maximum message you can encrypt is jumpValue * jumpValue) - or 25 in your case - characters, and your string is already longer (you can see that your "correct" matrix is 6x5).
So you need to iterator j not up to jumpValue, but up to the message length divided by jumpValue - and you need to round it up to the nearest whole number.
That also means that some of the characters in the last column of your matrix come from a position longer than the length of the input string, so you need to check for that.
The below code tackles both:
public static String jumpEncrypt(String message, int jumpValue) {
String jencrypt = "";
for (int i = 0; i < jumpValue; i++) {
for (int j = 0; j < (message.length() + jumpValue - 1) / jumpValue; j++) {
int index = i + j * jumpValue;
if (index < message.length()) {
jencrypt += message.charAt(index);
}
}
}
return jencrypt;
}
Note that the expression (message.length() + jumpValue - 1) / jumpValue (which is message.length() / jumpValue, but rounded up) is constant throughout both loops, so for efficiency, it's better to extract it into a local variable before the loops, to avoid an unnecessary evaluation of the expression for every loop.
So with this for loop code their is not much to go on but a simple fix might be
maybe j should be equal to one so message.charAt(i + j*jumpValue); it should not equal to
0 + 0*jumpValue) since that makes everything 0 and clears everything out to the basic.
so jencrypt = 0; no matter what its initial value was.
so maybe jumpValue - 1 for int i = 0;
Trying doing the math portion of the floor loop and see why its not adding up correctly.
for (int i = 0; i < jumpValue - 1; i++) {
for (int j = 0; j < (jumpValue); j++) {
jencrypt += message.charAt(i + j*jumpValue);
}
}
return jencrypt;
I am not completely sure if I am right but I did my best to understand I am pretty new still to coding! :)
If I use for (int j = 0; j <= (jumpValue); j++), and make no other changes, it works for me.
I started to read the famous "cracking the Coding Interview" book and I want to do the following exercice.
Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0.
Here is the author's solution :
public static void setZeros(int[][] matrix) {
int[] row = new int[matrix.length];
int[] column = new int[matrix[0].length];
// Store the row and column index with value 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length;j++) {
if (matrix[i][j] == 0) {
row[i] = 1;
column[j] = 1;
}
}
}
// Set arr[i][j] to 0 if either row i or column j has a 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if ((row[i] == 1 || column[j] == 1)) {
matrix[i][j] = 0;
}
}
}
}
I agree with the author about the main idea. We don't have to store the position of '0' in the matrix but only the position of the rows and columns that are concernerd. But what I found a little "strange" in her solution is that at the end, she did a loop on all the cells of the matrix, which is not necessary in my opinion.
Here is my solution :
static int[][] replaceMatrix(int[][] matrix){
int M = matrix.length;
int N = matrix[0].length;
boolean[] row = new boolean[M] ;
boolean[] column = new boolean[N];
for (int i =0; i< M; i++) {
for (int j = 0; j<N; j++ ){
if (matrix[i][j] == 0) {
row[i] = true;
column[j] = true;
}
}
}
for (int i =0; i<M; i++){
if (row[i]){
for (int k =0; k<N; k++){
matrix[i][k]=0;
}
}
}
for (int j =0; j<N; j++){
if (column[j]){
for (int k =0; k<M; k++){
matrix[k][j]=0;
}
}
}
I'am newbie in programmation so I'm not totaly sure about this. But in my solution, if we except the first step which is to store the 0 positions, my second part of my programme have a time complexity of O(M+N) while her solution has a complexity of O(M*N).
The problem is that the general complexity will be the same O(M*N + (M+N)) is the same that having the complexity O(2*M*N), no? (I'm not totally sure).
For example, if it's a matrix with M=N, so the two complexity of the two programs will be O(M^2).
I really want to know if there is a difference or not about complexity in this case?
ps : I read that the space complexity can be improved with a bit vector. But I really didn't understand. Can you just give me a general idea about it (in Java)?
Time complexity of your last two for loops is still O(M*N) as in worst case inner for loop will be running maximum value of k times.
There is technically no difference in your and the author's solution because both of you have traversed the entire matrix.So both codes are same ** if we have to consider big O notation**
In fact the author's code is a little bit( by little bit I do not mean a different time complexity) better. Here is the reason:
Suppose in your boolean array of rows, all rows are set true. Then in your case you will go through all rows and through each element of every row which is basically traversing the entire matrix.
Suppose in your boolean array of columns, all columns are set true. Then in your case you will go through all columns and through each element of every column which is basically traversing the entire matrix.
So you will in effect traverse the entire matrix twice. But the time complexity of the codes is the same because O(M*N) and O(2*M*N) is same.
You have already done saving space, since you used boolean data type.
I had a lot of trouble trying to find a solution to this answer because it's hard to search specifically about it. I will try my best to explain it well though.
Currently I have the following code:
for(int x = 0; x < 10000; x++){
for(int z = 0; z < 10000; z++){
if(!exists(x + ";" + z)){
return x + ";" + z;
}
}
}
This is pretty much what I want to do except the way the numbers will "generate" is like so:
0;0
0;1
0;2
0;3
...
0;9999
1;0
1;1
I would like the numbers to generate in the following way "or similar" while still ensuring that every combination exists.
0;0
1;0
1;1
0;1
I created an image to show how the numbers should generate. It can go from bottom to left or left to bottom. (See image)
Thanks!
int len = 3;
for (int i = 0; i < len; i++) {
for (int j = 0; j <= i; j++) //println(i+";"+j);
for (int k = i-1; k >= 0; k--) //println(k+";"+i);
}
In the code above len serves the purpose of defining the length of a square (len is 3 above which represents a 3 x 3). In your own code you picked 10000 but that is too large for printing values
What you want is easiest to do with two internal loops, one that handles vertical and the other horizontal. Other than that just arbitrarily pick which one handles the corner of each i iteration. In the code above the j loop handles the corner case
The algorithm you seem to be looking for is:
for(int distanceFromCorner = 0; distanceFromCorner < 10000; distanceFromCorner++) {
for(int otherAxis = 0; otherAxis <= distanceFromCorner; otherAxis++) {
if(!exists(distanceFromCorner + ";" + otherAxis))
return distanceFromCorner + ";" + otherAxis;
if(!exists(otherAxis + ";" + distanceFromCorner))
return otherAxis + ";" + distanceFromCorner;
}
}
Note that this (like your original algorithm) will be much slower than necessary if you want to generate a large number of IDs. (Optimizing this is a separate question)
After my array in the for loop reaches the last index, I get an exception saying that the index is out of bounds. What I wanted is for it to go back to the first index until z is equal to ctr. How can I do that?
My code:
char res;
int ctr = 10
char[] flames = {'F','L','A','M','E','S'};
for(int z = 0; z < ctr-1; z++){
res = (flames[z]);
jLabel1.setText(String.valueOf(res));
}
You need to use an index that is limited to the size of the array. More precisely, and esoterically speaking, you need to map the for-loop iterations {0..9} to the valid indexes for the flame array {0..flames.length()-1}, which are the same, in this case, to {0..5}.
When the loop iterates from 0 to 5, the mapping is trivial. When the loop iterates a 6th time, then you need to map it back to array index 0, when it iterates to the 7th time, you map it to array index 1, and so on.
== Naïve Way ==
for(int z = 0, j = 0; z < ctr-1; z++, j++)
{
if ( j >= flames.length() )
{
j = 0; // reset back to the beginning
}
res = (flames[j]);
jLabel1.setText(String.valueOf(res));
}
== A More Appropriate Way ==
Then you can refine this by realizing flames.length() is an invariant, which you move out of a for-loop.
final int n = flames.length();
for(int z = 0, j = 0; z < ctr-1; z++, j++)
{
if ( j >= n )
{
j = 0; // reset back to the beginning
}
res = (flames[j]);
jLabel1.setText(String.valueOf(res));
}
== How To Do It ==
Now, if you are paying attention, you can see we are simply doing modular arithmetic on the index. So, if we use the modular (%) operator, we can simplify your code:
final int n = flames.length();
for(int z = 0; z < ctr-1; z++)
{
res = (flames[z % n]);
jLabel1.setText(String.valueOf(res));
}
When working with problems like this, think about function mappings, from a Domain (in this case, for loop iterations) to a Range (valid array indices).
More importantly, work it out on paper before you even begin to code. That will take you a long way towards solving these type of elemental problems.
While luis.espinal answer, performance-wise, is better I think you should also take a look into Iterator's as they will give you greater flexibility reading back-and-forth.
Meaning that you could just as easy write FLAMESFLAMES as FLAMESSEMALF, etc...
int ctr = 10;
List<Character> flames = Arrays.asList('F','L','A','M','E','S');
Iterator it = flames.iterator();
for(int z=0; z<ctr-1; z++) {
if(!it.hasNext()) // if you are at the end of the list reset iterator
it = flames.iterator();
System.out.println(it.next().toString()); // use the element
}
Out of curiosity doing this loop 1M times (avg result from 100 samples) takes:
using modulo: 51ms
using iterators: 95ms
using guava cycle iterators: 453ms
Edit:
Cycle iterators, as lbalazscs nicely put it, are even more elegant. They come at a price, and Guava implementation is 4 times slower. You could roll your own implementation, tough.
// guava example of cycle iterators
Iterator<Character> iterator = Iterators.cycle(flames);
for (int z = 0; z < ctr - 1; z++) {
res = iterator.next();
}
You should use % to force the index stay within flames.length so that they make valid index
int len = flames.length;
for(int z = 0; z < ctr-1; z++){
res = (flames[z % len]);
jLabel1.setText(String.valueOf(res));
}
You can try the following:-
char res;
int ctr = 10
char[] flames = {'F','L','A','M','E','S'};
int n = flames.length();
for(int z = 0; z < ctr-1; z++){
res = flames[z %n];
jLabel1.setText(String.valueOf(res));
}
Here is how I would do this:
String flames = "FLAMES";
int ctr = 10;
textLoop(flames.toCharArray(), jLabel1, ctr);
The textLoop method:
void textLoop(Iterable<Character> text, JLabel jLabel, int count){
int idx = 0;
while(true)
for(char ch: text){
jLabel.setText(String.valueOf(ch));
if(++idx < count) return;
}
}
EDIT: found a bug in the code (idx needed to be initialized outside the loop). It's fixed now. I've also refactored it into a seperate function.
I'm working on this bacteria life game thing I have to make.
Basically I have a 2d string array let's say 20 by 20.
What would be the best way to check all 8 spots around a certain index. Each index is suppose to represent a bacteria. For each bacteria(index) I have to check to see if any of the 8 spots around this index has another bacteria in it, if the index has a bacteria in it, it's represented simply by a "*", asterik.
What would be the best way to go about checking all 8 spots around each index, because based on what is in the indices around a certain index I have to make certain changes etc.
The only idea I have come up with is having a bunch of if statements to check all 8 spots, I was wondering if there is a better way to do this
ex:
row 1 - www , row 2 = wOw , row 3 - www ,
if I am at the O index, what would be the best way to check all the index spots around it for a certain string.
Sorry, I am not very good at explaining my problems, bad english :o.
thanks for any of the help.
so you have something like this
char[][] table = new char[20][20]
for(int i = 0; i < 20; i++) {
for(int j = 0; j < 20; j++) {
int surroundingBacteria = 0;
for(int x = max(i-1,0); x < min(20,i+1); x++) {
for(int y = max(i-1,0); y < min(20,i+1); y++) {
if(table[x][y] == '*') surroundingBacteria++;
}
}
switch(surroundingBacteria) {
// put your case logic here
}
}
}
Here is how I've accomplished this in the past:
for(int x = -1; x<=1; x++){
if ( i+x < xLength && i+x >= 0){
for(int y = -1; y<=1; y++){
if(j+y < yLength && j+y >= 0){
//logic goes here
}
}
}
}