Merge four loops 'for' in one with different inner methods - java

I have four almost same loops in Java with different methods:
int Point;
for (int i = 0; i < 10; i++)
{
if (isLeft())
Point = i;
}
for (int i = 0; i < 10; i++)
{
if (isRight())
Point = i;
}
for (int i = 0; i < 10; i++)
{
if (isAbove())
Point = i;
}
for (int i = 0; i < 10; i++)
{
if (isUnder())
Point = i;
}
Can I merge all loops to one?

You could chain the conditions with the || operator:
for (int i = 0; i < 10; i++) {
if (isLeft() || isRight() || isAbove() ||isUnder()) {
Point = i;
}
}

You can't merge the loops if you want the current control flow to be retained.
Currently:
All four functions run 10 times each
isRight will not be called until isLeft will no longer be called, etc.
Point is a stronger function of the result of isUnder than isAbove, etc.
You could consider using || within an if statement, but I think you are likely to introduce bugs, assuming of course that the code currently runs as intended.

Not too sure what you are trying to do because all the conditions seem to change the value of point to the last value of the iterator that is 9.
but the snippet bellow can allow you to do so.
for (int i = 0; i < 10; i++){
if (isLeft())
int Point = i;
if (isRight())
int Point = i;
if (isAbove())
int Point = i;
if (isUnder())
int Point = i;
}
another version of this will joint all the conditions
for (int i = 0; i < 10; i++) {
if (isLeft() || isRight() || isAbove() ||isUnder()) {
Point = i;
}
}

Related

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. :)

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

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.

How would I optimize this look for unique number Algorithm function [duplicate]

This question already has answers here:
How to count distinct values in a list in linear time?
(3 answers)
Closed 7 years ago.
For this Algorithm assignment in class I have to find all the unique values in a 1000x250 2D array.
The data is between 2000000 to 2200000. All the data is stored in a 2D int array called data.
The problem I am having is that it takes a bit of time to run this and my prof said we can't use other data sets and also we need to optimize our code so it runs at a good speed.
int[] uniqueValues = new int[200000];
boolean isUnique = true;
int uniqueCounter = 0;
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
for (int x = 0; x < uniqueCounter; x++) {
if (data[i][j] != uniqueValues[x]) {
isUnique = true;
} else {
isUnique = false;
break;
}
}
if (isUnique) {
uniqueValues[uniqueCounter] = data[i][j];
uniqueCounter++;
}
}
}
Well if you allocate 200000 ints for the result anyway, you can use them as counters for each value, then collect the ones that only occur once:
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
uniqueValues[data[i][j] - 2000000]++;
}
}
int uniqueCounter = 0;
for (int i = 0; i < uniqueValue.length; i++) {
if (uniqueValues[i] == 1) {
uniqueValues[uniqueCounter++] = i + 2000000;
}
}

Sort an array alphabetically

I need to sort book objects by their titles in a simple way. However, the selection sort algorithm I wrote isn't working properly and just moves the books around, but with no apparent order. What am I doing wrong?
int j;
int b;
for (int i = 0; i < 20 - 1; i++) {
int minIndex = i;
for (j = i + 1; j < 20; j++) {
b = (bookA[j].getTitle().compareTo(bookA[minIndex].getTitle()));
if (b < 0) {
minIndex=j;
}
}
Book temp = bookA[i];
bookA[i] = bookA[j];
bookA[j] = temp;
}
for (int z = 0; z < 20; z++)
System.out.println(bookA[z].toString());
You're using j as an index in bookA[i] = bookA[j];. The problem is that you're overriding the value of j at every iteration, so when it finally gets to bookA[i] = bookA[j]; it will always be 20.
What you want is to replace it with bookA[minIndex]. The resulting code would look like this:
int j;
int b;
for(int i=0;i<20-1;i++){
int minIndex=i;
for(j=i+1;j<20; j++) {
b=(bookA[j].getTitle().compareTo(bookA[minIndex].getTitle()));
if(b<0){
minIndex=j;
}
}
Book temp = bookA[i];
bookA[i] = bookA[minIndex];
bookA[minIndex] = temp;
}
for(int z=0;z<20;z++)
System.out.println(bookA[z].toString());

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.

Categories