Is it possible to add conditional for loop in nested ones? - java

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.

Related

How to print ASCII patterns in C# but using Java syntax?

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

printing numbers with nested loops

I have to print the following numbers using nested loops, and I kinda have an idea how, but not how to execute it.
000111222333444555666777888999
000111222333444555666777888999
000111222333444555666777888999
My code so far is something like:
public class opgave_2 {
public static void main(String[] args) {
final int first = 3;
final int second = 3;
final int third = 9;
for (int i = 0; i <= first ; i++) {
for (int j = i; j <= second; j++) {
for (int k = j; k <= third; k++) {
System.out.print(i);
}
}
}
}
}
You should proceed by steps to resolve such problem.
First, you want to print a number 3 times :
int myNumber = 0;
for(int i=0; i<3; i++) {
System.out.print(myNumber);
}
Second, you want to repeat it 9 times and your number to vary from 0 to 9 (seems like an index of loop) :
for(int myNumber=0; myNumber<=9; myNumber++) {
for(int i=0; i<3; i++) {
System.out.print(myNumber);
}
}
Third, you want to display this line 3 times :
for(intj=0; j<3; j++) {
for(int myNumber=0; myNumber<=9; myNumber++) {
for(int i=0; i<3; i++) {
System.out.print(myNumber);
}
}
System.out.println(""); //new line
}
What about something like this:
for (int i = 0; i < 3; i++) {
for (int j = 0; j <= 9; j++) {
System.out.printf("%1$s%1$s%1$s", j);
}
System.out.println();
}
Which uses 2 nested loops. The first to print the line 3 times, and the second to print the numbers per line
you can use a loop, that loops 3 times. in that you put a loop that prints every number from 0 to 9 3 times in a row within the same line
for(int a = 0; a < 3; a++){
for(int i = 0; i < 10; i++){
System.out.print(i+""+i+""+i);
}
System.out.println(); //for the new line
}
or
for(int a = 0; a < 3; a++){
for(int i = 0; i < 10; i++){
System.out.print(i);
System.out.print(i);
System.out.print(i);
}
System.out.println(); //for the new line
}
this should do

Java sudoku Solver Method

I'm trying out this code for a project where we do the fill grid and evaluate methods for a given sudoku grid via three urls that we can interchange within the code. I'm not interested in efficiency at this point because I'm still trying to get a handle on Java. So far this is the code I have for the evaluate method
I understand the logic behind the first two for loops for the box but I'm trying to understand the second two
EDIT: I'm asking if I what I wrote for the box checker is correct because it still returns false even though the written grids are all correct sudoku boards
public boolean evaluate() {
// check row
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
for (int k = j + 1; k < 9; k++) {
if (gridButton[i][j].getText().equals(gridButton[i][k].getText())) return false;
}
}
}
// check box
for (int i = 0; i < 9; i += 3) {
for (int j = 0; j < 9; j += 3) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
if (gridButton[i][j].getText().equals(gridButton[k][l].getText())) return false;
k += 1;
}
}
}
}
// check col
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
for (int k = i + 1; k < 9; k++) {
if (gridButton[i][j].getText().equals(gridButton[k][j].getText())) return false;
}
}
}
return false;
}
I worked with my professor for a viable row checker and I adapted it myself for the col checker but I'm still not totally sure about how to write the box checker.
The Box algorithm in your code does 9x9x3x3 == 729 comparisons.
Perhaps a better approach would be to use a HashSet across each row, column, or box. Once a duplicate value is found in the set, it can bail out.
With using a Set, there's 9x3x3 == 81 looksup and insertions to be made. Assumption is that Set insertion and lookup are both O(1)
// check box
HashSet<String> set = new HashSet<String>();
for (int i = 0; i < 9; i++) { // for each major 3x3 box
set.clear(); // start with an empty "set"
// examine each cell in the box. If the cell's value is already in
// "set", then we have a duplicate and should exit. Otherwise, add
// the cell's value to the set
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
int row = (i / 3) + r;
int column = 3*(i%3) + c;
String val = gridButton[row][column].getText();
if (set.contains(val) {
return false; // the value of the cell was already found, bail
}
set.add(val); // not found, add it to the set
}
}
}
You can apply the same technique to the "check row" and "check column" algorithm and have less comparisons to make as well. That's an exercise I'll leave up to you to solve.
And if we were comparing integers instead of text strings, we could use a simple Boolean array instead of a HashSet instance. :)

Move left if there is a zero

I am trying to create a program that will take an array of integers, say {2,0,32,0,0,8} that can be of any length, and make it so all of the nonzero numbers are to the left at the lower indexes, and all the zeros are moved to the end.
For example, {2,0,32,0,0,8} becomes {2,32,8,0,0,0}.
This array can be of any length and contain any nonnegative integers.
This is what I have so far:
public static int[] moveLeft(final int[] a) {
for (int i = 0; i < a.length; i++) {
if (a[i] != 0) {
for (int j = 0; j < a.length; j++) {
if (a[j] == 0) {
a[j] = a[i];
a[i] = 0;
}
}
}
}
return a;
}
However, when I do this, it doesn't work for the first and second characters. If I have {1,2,0,1} it will return {2,1,1,0} when it should return {1,2,1,0}. Any help?
Your inner loop should stop before index i. Change this
for (int j = 0; j < a.length; j++) {
to
for (int j = 0; j < i; j++) {
And then your code works for me.

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.

Categories