Java for loops while keeping variable within a range - java

Im trying to run a two for loops that iterate over something like colored large square (for example 300x300) and replacing it with the colors(or pixels) of a smaller square (say 100x100) which is what k and l represent.
Essentially, I was wondering how to keep k and l running between 0-100 and restarting once it hits 100, but also keep i and j running the whole time. I tried used 4 nested for loops but it did not work properly, although I'm starting to think that may be a solution, but that would be very inefficient.
Please let me know if this sounds a little confusing I will try my best to explain more clearly, thanks.
excuse the psuedocode
for (i=0; i < width; i++)
for (j=0; i< height; j++)
set(i, j , pixel(k,l));

The problem seems to be to tile an image onto another image. You have width and height for the target image's dimensions, so let's say sourceWidth and sourceHeight are the source image's dimensions (100 by 100, in your example).
To tile an image, you want k == i % sourceWidth and l == j % sourceHeight, so that the pixel you read from the source image "wraps around" the boundaries. These should be invariant conditions. The simplest way to satisfy them is to declare them that way directly:
for(int i = 0; i < width; ++i) {
int k = i % sourceWidth;
for(int j = 0; j < height; ++j) {
int l = j % sourceHeight;
set(i, j, pixel(k, l));
}
}
This does a lot of % operations, which could be quite inefficient, but it gives us a correct piece of code to transform. If we are incrementing k and l, then there are two properties needed to maintain the invariants:
k and i are incremented in unison; and l and j are incremented in unison.
When k reaches sourceWidth it must wrap back to 0, likewise for l and sourceHeight.
for(int i = 0, k = 0; i < width; ++i, ++k) {
if(k == sourceWidth) { k = 0; }
for(int j = 0, l = 0; j < height; ++j, ++l) {
if(l == sourceHeight) { l = 0; }
set(i, j, pixel(k, l));
}
}
Note that the for loop initialiser and stepper now declare and update two variables, for both loops. This is allowed in Java.
This is likely to be faster than doing a lot of % operations, but note that branching with if statements can also slow down an algorithm, so you may want to benchmark it to be sure.
In the special case where source image's dimensions are powers of two, we can achieve the same result with a fast bitwise operation: i % sourceWidth will be equivalent to i & (sourceWidth - 1):
// special case: sourceWidth and sourceHeight are powers of 2
int wMask = sourceWidth - 1, hMask = sourceHeight - 1;
for(int i = 0, k = 0; i < width; ++i, ++k) {
for(int j = 0, l = 0; j < height; ++j, ++l) {
set(i, j, pixel(i & wMask, j & hMask));
}
}

It could be done by something like this:
for (i = 0; i < width; i++) {
for (j = 0; j < height; j++) {
if(k > 100) {
k = 0;
}
if(l > 100) {
l = 0;
}
k++;
l++;
set(i, j , pixel(k,l));
}
}

Related

Can you help me to calculate time complexity of this algorithm?

public static void complexityexample(int n) {
int count = 0;
int k = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
count++;
}
k *= 2;
for (int t = 0; t < n; t++) {
count++;
}
System.out.println(count);
}
}
Can anyone write me the answer?
for example , I know that nuber of operations in the for loop is 2N+2,
and number of operations in count++; is N
but what for the other parts.
Time complexity is O(2n). The bottle neck is :
for(int j = 0; j < k; j++){
count++;
}
Since k increases exponentially every iteration of i.
In the i'th iteration, k = 2i-1. This means iterating all values from j to k is O(k) = O(2i).
Now, sum it all up for all iterations:
20 + 21 + 22 + ... + 2n-1 = 2n - 1
Where last equality comes from sum of geometric series
Note that the next inner loop:
for (int t = 0; t < n; t++) {
is not influencing the time complexity (in terms of asymptotic notation), since it adds O(n) time for each iteration of i, and this gets quickly suppressed by the exponential behavior of the first inner loop.
If you want to count the value of count at the end, it is the summation of the first inner loop, which as said is (2n)-1, and the second inner loop, which is sum{n | for each i} = n2.
(2^n)+(n*n)
as them main loop is
for (int i = 0; i < n; i++) {
2^n from :
for (int j = 0; j < k; j++) {
count++;
}
and n*n from:
for (int t = 0; t < n; t++) {
count++;
}
1st row ) 1 operation.
2st row ) 2 operations.
3rd row ) 1+n+1+n = 2N+2.
4 ) 2N+2
5)N
7) N
9)2N+2
10)N
13)1
Is this right.
And after all math calculations the final result is : 14N^2 + 22N + 11 - operations.
A precise methodology using Sigma notation would be:
Empirically verified:
When n = 10, number of overall iterations is 1123.
When n = 25, number of overall iterations is 33555056.
When n = 50, it took for ever to execute (I had to change variables type from int to long).
Indeed, this non polynomial algorithm is expensive.

Sieve of Eratosthenes - Implementation returning some non-prime values?

I implemented the Sieve of Eratosthenes in Java, from pseudocode:
public static void sieveofEratosthenes(int n) {
boolean numArray[];
numArray = new boolean[n];
for(int i = 0; i < n; i++)
numArray[i] = true;
int a = 0;
for(int i = 2; i < Math.sqrt((double)n); i++) {
if(numArray[i]) {
for(int j = (int)Math.pow(i, 2); j < n; a++) {
numArray[j] = false;
j += (a * i);
}
}
}
for(int i = 2; i < n; i++) {
if(numArray[i])
System.out.println(i);
}
}
The output it gives me, when i is 15:
2
3
5
7
8
11
12
13
14
Why are some of these values incorrect? I believe my error is in how I define and use the bool array. Thanks!
for(int j = (int)Math.pow(i, 2); j < n; a++) {
numArray[j] = false;
j += (a * i);
}
should read
for(int j = (int)Math.pow(i, 2); j < n; j+=i) {
numArray[j] = false;
}
How SoE works is that it takes each number and "deletes" all numbers following it that are divisible by it. So basically each number x + k*x where k > 0. This can be done by simply adding x to the initial x^2 and then adding iteratively x to it. Here:
for(int j = (int)Math.pow(i, 2); j < n; a++) {
numArray[j] = false;
j += (a * i);
}
You are not adding x but a*x, so you will skip some numbers as a is being incremented (so you will remove 4,6,10,16 etc, see the pattern? it adds 2,4,6 etc to the initial value) so you should stick with:
for(int j = (int)Math.pow(i, 2); j < n; j+=i) {
numArray[j] = false;
}
The problem is at line
j += (a * i);
In loop, this statement gradually multiplies the j by a*i and add it with j.So replace above line with,
j = (a * i);
It will work.
And yes,initialize
a=2
because we don't want numarray[0] or numarray[1] to initialize or use.
Do comment if any query. Thanks
This doesn't directly address your question, but since it's already been answered, I don't see any point in repeating it. Looking at your code, though, I suggest using integer multiplication instead of Math.pow and Math.sqrt to get slightly better performance such as:
for(int i = 2; i*i < n; i++) {
if(numArray[i]) {
for(int j = i*i; j < n; j += i) {
numArray[j] = false;
}
}
}
Admittedly these calls will only be made once per iteration of the outer loop, so the improvement may not be very dramatic. But, calling Math.pow and Math.sqrt are likely to be much more compute intensive than a single integer multiplication. Also, if Java performs sufficiently sophisticated optimization, i*i may only get computed once and used in both places saving even more compute cycles. There's also no risk of integer overrunning in this case since i*i is bounded above by the integer n.

Transpose a NxN matrix

I have a NxN matrix and it trying to transpose it by this code:
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < mat_size; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
it doesn't work, what is the problem? thanks in advance.
It doesn't work since you're swapping the whole matrix with itself. What you need to do is exchange the upper triangle with the lower one:
for(int j = 0; j < i; ++j) {
is one way.
Going from 0 to mat_size will get you reorder the whole matrix two times, getting the original one again.
change to :
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
You need to swap only if j > i. So the inner loop must start at i+1. For j==i (the center diagonal) no swapping is needed, too.
Your solution doesn't work because you're actually swapping twice (once with j=x and i=y and once with j=y and i=x.
For example the (2,5) is swapped for i=2,j=5 and i=5,j=2. Swap twice does nothing.
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
This is because the elements that you swap in the lower triangle of the matrix gets swapped again when the iteration reaches the other side of the diagonal. That is the element is swapped twice which results in nothing.
Try:
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}

Simple for loop is taking time to execute in android

I have implemented a code in java which has a for loop which varies from 0 to 0x10000 times.
Now i am importing this code into android and running the same code.
Problem if that:
In Core java loop executes with in 2 seconds at max.
But when same loop is being executed in android it is taking 4 minutes (Disgusting)
Please can any one help me out from this, i am pasting my loop for your understanding:
for (int r = 0; r < 0x10000; r++) {
for (int j = 0; j < password.length; j += 4) {
long[] key = {0, 0, 0, 0};
for (int i = 0; i < 4; i++) {
if (i + j < password.length) {
//do something
}
}
//calling one method.
}
}
Basically main loop varies upto 64000 times. Please suggest.
May be this can help a little:
int maxR = 0x10000;
int passwordLength = password.length;
for (int r = 0; r < maxR; r++) {
for (int j = 0; j < passwordLength; j += 4) {
long[] key = {0, 0, 0, 0};
for (int i = 0; i < 4; i++) {
if (i + j < passwordLength) {
//do something
}
}
//calling one method.
}
}
But I think that the thing to optimized is probably the content of your last for loop and the method you call after it...
[EDIT] If you don't access to other items of the "key" array than the one at index i, you can do what Joop Eggen suggested:
int maxR = 0x10000;
int passwordLength = password.length;
long[] key = {0, 0, 0, 0};
for (int r = 0; r < maxR; r++) {
for (int j = 0; j < passwordLength; j += 4) {
for (int i = 0; i < 4; i++) {
key[i] = 0;
if (i + j < passwordLength) {
//do something
}
}
//calling one method.
}
}
long[] key = new long[4];
int incompleteFourer = password.length % 4;
int n = password.length - incompleteFourer ;
for (int r = 0; r < 0x10000; r++) {
for (int j = 0; j < n; j += 4) {
for (int i = 0; i < 4; i++) {
key[i] = 0;
//do something
}
//calling one method.
}
if (incompleteFourer != 0) {
int j = n;;
//calling one method.
}
}
Memory allocation of key only once; assume "do something" only considers key[i].
Index of j to always have full 4 elements; "calling one method" might not handle some of the three last elements.
The last 1 to 3 elements are handled separately.
NetBeans IDE has a nice profiler, and maybe the same bottleneck concerns both loops. At least measure times of indiivual calls on Android; maybe it is a slow Dalvik implementation of some basic function.

2D array printing letters in middle of grid in forward direction

public void fill(ArrayList<String> a1) {
int i = 0;
while (i < a1.size()) {
if (i == 0) {
for (int j = 0; j < a1.get(i).length(); j++)
crossword[ROWS / 2][(COLUMNS / 4) + j] = a1.get(i)
.charAt(j);
i++;
}
if (i == 1) {
outerloop: for (int t = 0; t < ROWS; t++)
for (int s = 0; s < COLUMNS; s++)
for (int j = 0; j < a1.get(i).length(); j++)
if (crossword[t][s] == a1.get(i).charAt(j)) {
for (int z = 0; z < j; z++)
crossword[t - z - 1][s] = a1.get(i).charAt(
z);
for (int h = j + 1; h < a1.get(i).length(); h++)
crossword[t + h - j][s] = a1.get(i).charAt(
h);
crossword[t][s] = a1.get(i).charAt(j);
break outerloop;
}
i++;
}
}
}
The above is my method to make the first two words of a list of words intersect each other on a crossword puzzle board. My question is for the part:
for (int z = 0; z < j; z++)
crossword[t - z - 1][s] = a1.get(i).charAt(z);
It takes the letters in front of the intersection point and prints them backwards above the intersection row. My brain is overloaded with different things right now and I can't seem to understand how to make the letters go in the right order. I can't attach an image to display my problem but for example the vertical word "throwing" which intersects with horizontal word "clowning" at the letter "o" prints out "rht" before the o (when it should be printing out "thr"). Could someone help? Would be much appreciated!
This will do the trick:
for (int z = 0; z < j; z++)
crossword[t - j + z][s] = a1.get(i).charAt(z);
P.S. This question hasn't been closed yet (even though you did respond to your question). You should flag this answer (or, if you don't feel like giving me points, an answer that you put in) as correct, so that the question doesn't remain in the unanswered section!

Categories