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.
Related
Code below is for pattern a, feel like once I get a I could get the others.
I like the array[int].length syntax in Java and was helpful to get the pattern to print as shown in the picture. But I do not think such a thing exists in C#.
class Main {
public static void main(String[] args)
{
char[][] arr = new char[10][10];
int starCount = 10;
for(int i = 0; i < arr.length; i++)
{
for(int j = 0; j < starCount; j++)
{
arr[i][j] = '*';
}
for(int k = starCount; k < arr[i].length; k++)
{
arr[i][k] = '-';
}
starCount--;
}
for(int a = 0; a < arr.length; a++)
{
for(int b = 0; b < arr[a].length; b++)
{
System.out.print(arr[a][b]);
}
System.out.println();
}
}
}
This code prints the * in a decreasing fashion but I am struggling with how to replace the empty elements of the array with the - character as shown in the image.
class MainClass {
public static void Main (string[] args)
{
char[ , ] arr = new char[10,10];
int starCount = 10;
for(int i = 0; i < arr.Length; i++)
{
for (int j = 0; j < starCount; j++)
{
arr[i , j] = '*';
}
for (int k = 0; ) //IDK WHAT TO DO TO ASSIGN ARR[I , K] = '-';
starCount--;
}
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
Console.Write(arr[i , j]);
}
Console.WriteLine();
}
}
}
You can use two nested for loops and one if else statement to print all of these patterns. This is Java code, but I think it can be easily converted to C#:
int n = 5;
for (int i = -n; i <= n; i++) {
for (int j = -n; j <= n; j++) {
// a) if (i + j <= 0)
// b) if (i + j >= 0)
// c) if (i <= j)
// d) if (Math.abs(i) + Math.abs(j) <= n)
if (i + j <= 0)
System.out.print("*");
else
System.out.print("-");
}
System.out.println();
}
Output (combined):
a) b) c) d)
*********** ----------* *********** -----*-----
**********- ---------** -********** ----***----
*********-- --------*** --********* ---*****---
********--- -------**** ---******** --*******--
*******---- ------***** ----******* -*********-
******----- -----****** -----****** ***********
*****------ ----******* ------***** -*********-
****------- ---******** -------**** --*******--
***-------- --********* --------*** ---*****---
**--------- -********** ---------** ----***----
*---------- *********** ----------* -----*-----
See also: Output an ASCII diamond shape using loops
Here's a different approach to the original problem, which might be easier for you to convert.
Build a string of 10 stars and 9 dashes, e.g. hard-coded that would be:
String line = "**********---------";
Now print a 10 rows with substrings of that string:
for (int i = 0; i < 10; i++)
System.out.println(line.substring(i, i + 10));
Output
**********
*********-
********--
*******---
******----
*****-----
****------
***-------
**--------
*---------
If the size is dynamic, based on an int value in variable starCount, then in Java 11+ you can use the repeat() method:
String line = "*".repeat(starCount) + "-".repeat(starCount - 1);
for (int i = 0; i < starCount; i++)
System.out.println(line.substring(i, i + starCount));
That one should be easy to do in C#. See: Best way to repeat a character in C#.
In versions of Java below 11, you can build a char[]:
char[] line = new char[2 * starCount - 1];
Arrays.fill(line, 0, starCount, '*');
Arrays.fill(line, starCount, line.length, '-');
for (int i = 0; i < starCount; i++)
System.out.println(new String(line, i, starCount));
The easiest way would be to look at the C# documentation for the Array class. There you would find that the Array class has a GetLength() method, that returns what the length property of a Java array returns.
Using that method you can change your code to
class MainClass {
public static void Main (string[] args)
{
char[ , ] arr = new char[10,10];
int starCount = 10;
for(int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < starCount; j++)
{
arr[i , j] = '*';
}
for (int k = starCount; k < arr.GetLength(1); k++)
{
arr[i , k] = '*';
}
starCount--;
}
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write(arr[i , j]);
}
Console.WriteLine();
}
}
}
For some reason when you switched from java to C# you went from using jagged arrays:
//java
char[][] arr = new char[10][10];
To rectangular arrays:
//c#
char[ , ] arr = new char[10,10];
This undoubtedly makes your life more hard work because it means a lot more has to change. C# supports jagged arrays in exactly the same way Java does, and in fact if I hadn't written "//java" above you wouldn't have been able to tell whether it was C# or java because they're the same
I like the array[int].length syntax in Java ... But I do not think such a thing exists in C#.
It absolutely does, and you need to change just one single character to get it: properties in C# are named in Pascal case, so you want Length, not length
In fact, the logic of that entire block of java you have will work just fine in C# - just paste it in and change the following minor changes:
length -> Length
System.out.print -> Console.Write
System.out.println -> Console.WriteLine
In an ordinary nested for-loop, is it possible to put a condition to determine whether to run a specific for loop in a nested loop?
For example, in a code like below, is it possible to skip second for-statement(int j) when int i of the first loop is < 3?
for(int i = 0; i < 5; i++) {
for(int j = 0; j < 3; j++) {
for(int k = 0; k < 9; k++) {
//hell a lot of codes
}
}
}
so that only when i < 3, the actual executed code looks like this?
for(int i = 0; i < 5; i++) {
for(int k = 0; k < 9; k++) {
//hell a lot of codes
}
}
The reason why I want to do this is that the inner-most codes are quite long as well as the number of the for loops (about 10 nested), and really don't want to repeat them again. I can think of doing this with methods, but I am not quite familiar with methods and OO programming.
Much appreciated,
Generally, I'd probably extract the code to a separate method. But here's a workaround if you don't want to do that:
for(int i = 0; i < 5; i++) {
for(int j = 0; j < (i < 3 ? 1 : 3); j++) {
for(int k = 0; k < 9; k++) {
//hell a lot of codes
}
}
}
This way, if i < 3, the j loop will only execute once.
The method approach would roughly look something like this:
void outer() {
for(int i = 0; i < 5; i++) {
if(i < 3) {
inner(i, 0);
} else {
for(int j = 0; j < 3; j++) {
inner(i, j);
}
}
}
}
void inner(int i, int j) {
for(int k = 0; k < 9; k++) {
//hell a lot of codes
}
}
You may want to make the methods static, or private, or remove the parameter(s), or add a return type, etc. It's hard to say with just the code in your question.
I have an ArrayList and I want to create a method that will turn it into a 2d array, int[][].
This new 2d array will represent a matrix and it has to be square, so for example if I use [8, 2, 3, 0] the ressult will be {8,2}
{3,0}
public static int[][] convertIntegers(ArrayList<Integer> integers){
int m = (int) Math.sqrt(integers.size());
int[][] ret = new int[m][m];
int cont = 0;
for(int i=0; i<m+1 ; i++)
{
for(int j=0; j<m; j++)
{
cont = cont + 1;
ret[i][j] = integers.get(cont);
;
}
}
return ret;}
Your implementation is almost ok, except for some off-by-one errors:
You need to increment cont after the integers.get call, not before. If you increment before, then the first element of the list will be skipped. An easy way to fix that is to move the incrementing inside the inner loop, counting it together with j.
The outer loop should go until i < m instead of i < m + 1
With the errors fixed:
for (int i = 0, cont = 0; i < m; i++) {
for (int j = 0; j < m; j++, cont++) {
ret[i][j] = integers.get(cont);
}
}
Btw, another way is without using cont at all,
calculating the correct position using i, j and m:
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
ret[i][j] = integers.get(i * m + j);
}
}
Im doing some personal work, and I am using this array that I thought of, but I cant figure out whats the array is after the code stops running.
int cnt = 0;
int[][] numarray = new int[2][3];
for(int i = 0; i < 3; i++) {
for(int j = 0; j< 2; j++) {
numarray[j][i] = cnt;
cnt++;
}
}
I am pretty sure that it ends at [2][1] but I am not 100% sure of it
Just tried this code:
int cnt = 0;
int[][] numarray = new int[2][3];
for(int i = 0; i < 3; i++) {
for(int j = 0; j< 2; j++) {
numarray[j][i] = cnt;
cnt++;
System.out.print(numarray[j][i]+" ");
}
System.out.println("");
}
and got this result:
0 1
2 3
4 5
The 'cnt' is incremented by 1 for each iteration. That's why you have 0,1,2,3,4,5.
Also learn how to use debugger in an IDE, you can then explore the value of i, j, cnt by yourself.
why don't you try this?
int cnt = 0;
int[][] numarray = new int[2][3];
for(int i = 0; i < 3; i++) {
for(int j = 0; j< 2; j++) {
numarray[j][i] = cnt;
System.out.println(String.format("array[%d[%d]=%d",j,i,numarray[j][i]));
cnt++;
}
}
you can iterate the array after code finish
for(int i = 0; i < 2; i++) {
for(int j = 0; j< 3; j++) {
System.out.print(numarray[i][j]+" ");
}
System.out.println();
}
summary: cnt is incremented by 1 for each iteration in the inner for loop.
cnt is being incremented by 1 i.e. cnt++ is same as cnt = cnt + 1;
so count values increment from 0 i.e. 0,1,2,3,4,5... Also note, the value of cnt is assigned to the array being created, where you have numarray[j][i] = cnt;
You can simply printout the value using System.out.println(cnt);
I have an array called blockHeights, which contains 3 values inside of it, namely 1,2,3. So blockHeights[0] is equal to 1.
I also have a loop:
for (int i = 1; i <= blockHeights.length; i++)
In the first time around the loop, I want to create a variable called totalBlockHeights where it is
int totalBlockHeights = blockHeights[0] + blockHeights [1] + blockHeights [2];
However, in the next loop I want that variable to change, so that it only adds blockHeights[1] and blockHeights[2] together, ignoring blockHeights[0].
How would I go about doing this?
Try the following (I'm assuming the third iteration should only include blockHeights[2], following the pattern):
for (int i = 1; i <= blockHeights.length; i++) {
int totalBlockHeights;
for (int j = i - 1; j < blockHeights.length; j++) { // all block heights from here onwards
totalBlockHeights += blockHeights[j];
}
// do whatever
}
Well, if you want the sum of your array, and the sum of the array without first value
int totalBlockHeights = 0;
for(int i = 0; i < blockHeights.length; i++){
totalBlockHeights += blockHeights[i];
}
System.out.println(totalBlockHeights);
System.out.println("totalBlockHeights without first value = " + (totalBlockHeights - blockHeights[0]));
this way you only loop once
Try following code:
public class Loop {
public static void main(String[] argv) {
int[] blockHeights = new int[] {1, 2, 3};
int totalBlockHeights = 0;
for(int i = 0; i < blockHeights.length; i++) {
totalBlockHeights = 0;
for(int j = i; j < blockHeights.length; j++) {
totalBlockHeights += blockHeights[j];
}
System.out.println(totalBlockHeights);
}
}
}
int[] blockHeights = new int[] { 1, 2, 3 };
int totalBlockHeights = 0;
int customBlockHeights = 0;
for (int i = 0; i < blockHeights.length; i++) {
totalBlockHeights += blockHeights[i];
if (i == 0) {
continue;
}
customBlockHeights += blockHeights[i];
}
System.out.println(totalBlockHeights);
System.out.println(customBlockHeights);
This will print:
6
5
You dont need two for to achieve that.
you can perform this on two for loop outer loop for (int i = 1; i <= blockHeights.length; i++), and in inner loop (take a variable j) you can do like int totalBlockHeights = totalBlockHeights + blockHeights[j], and for i<j, you can just continue the for loop.
as answered by btrs20