Stopping an inner loop after one correct iteration - java

The problem in the code is in the goldbach method. I want to stop iteration of the inner two loops after the inner most loop has found one pair of numbers, but I am not getting how to exit just those two loops. In other words, I only want to find only one pair per i integer created by the outermost for loop, and then move on to the next integer i.
Below is my code:
import java.util.Arrays;
import java.awt.List;
import java.util.ArrayList;
// finding prime numbers using sieve of Eratosthenes and golbach's conjecture
public class Test {
public static void main(String[] args) {
int[] num = new int[1000000];
for (int i = 2; i <= num.length; i++) {
num[i - 1] = i;
}
Test.sieve(num);
Test.goldbach(num);
}
public static void sieve(int[] array) {
for (int i = 2; i < Math.sqrt(array.length); i++) {
if (array[i - 1] == 0) {
continue;
}
for (int j = 2 * i; j <= array.length; j += i) {
array[j - 1] = 0;
}
}
for (int i = 0; i < array.length; i++) {
if (array[i] != 0) {
//System.out.print(array[i] + " ");
}
}
//System.out.println(Arrays.toString(array));
}
public static void goldbach(int[] array) {
for (int i = 2; i <= 1000000; i += 2) { //to go through every even integer
for (int j = 0; j <= i; j++) {
for (int k = 0; k <= i; k++) {
System.out.println("two prime numbers that add to " + i + " are " + array[j] + " and " + array[k]);
break;
}
}
}
}
}
}

You could set the value of j in your second loop. eg.
for (int i = 2; i <= 1000000; i += 2) { //to go through every even integer
for (int j = 0; j <= i; j++) {
for (int k = 0; k <= i; k++) {
System.out.println("two prime numbers that add to " + i + " are " + array[j] + " and " + array[k]);
j = i + 1; // This will end the outer loop as well.
break;
}
}
}
}

use a label to break (or continue) a loop other than the inner one:
found:
for (int j = 0; j <= i; j++) {
for (int k = 0; k <= i; k++) {
System.out.println("two prime numbers that add to " + i + " are " + array[j] + " and " + array[k]);
break found;
}
}
}
or use an additional method and return - more indicated if that new method has an own clear function (and better name)
public static void goldbach(int[] array) {
for (int i = 2; i <= 1000000; i += 2) { //to go through every even integer
primeAdd(i);
}
}
private static void primeAdd(int i) {
for (int j = 0; j <= i; j++) {
for (int k = 0; k <= i; k++) {
System.out.println("two prime numbers that add to " + i + " are " + array[j] + " and " + array[k]);
return;
}
}
}
but, as already commented by bureaquete, there is no need for the inner loop since it is always being terminated.

Related

How to solve Index 1 out of bounds for length 1

I have a method jsonProductItems() which return a map with String key and value.
public Map<String, String> jsonProductItems() throws IOException {
List<String> products = new ArrayList<>();
Map<String, String> productsAndIdentifier = new LinkedHashMap<>();
for (Item item : example.getItems()) {
products.add(item.getName());
}
for (int i = 0; i < products.size(); i++) {
productsAndIdentifier.put(indetifier.get(i), products.get(i));
}
System.out.println();
return productsAndIdentifier;
}
When in the same class in other method I want to do a matrix. When value from matrix is equal with a key from map returned by jsonProductItems() method, will print value of this key. But at line if(("" + sumByRemainder.get(i) + j).equals(entry.getKey())) have java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1. How to solve this problem? And why in this case it appear?
for (int i = 0; i <= rows; i++) {
System.out.print(sumByRemainder.get(i) + " ");
for (int j = 1; j <= columns; j++) {
if (i == 0) {
System.out.print(" " + j);
System.out.print(" ");
} else {
indetifier.add("" + sumByRemainder.get(i) + j);
for (Map.Entry<String, String> entry : jsonProductItems().entrySet()) {
if(("" + sumByRemainder.get(i) + j).equals(entry.getKey())){
System.out.println(jsonProductItems().get(entry.getKey()));
}else{
System.out.print("" + sumByRemainder.get(i) + j + " ");
}
}
Length of 1 means there is only an element at index 0 - so you should do something like (i - 1)
As some of the variables you have used seems unknown here for the other people like me, I think this code snippet is the culprit for your problem:
for (int i = 0; i <= rows; i++) {
System.out.print(sumByRemainder.get(i) + " ");
for (int j = 1; j <= columns; j++) {
//... your code
}
}
You can try the loops limit like this:
for (int i = 0; i < rows; i++) {
System.out.print(sumByRemainder.get(i) + " ");
for (int j = 1; j < columns; j++) {
// you code here
}
}
Just give a check in your looping limit for both of the loops.

How to make the for inner loop more efficient?

I am new to Java and there's this one question that makes me wonder. How to make the for inner loop more efficient in this code?
for (int i = 2; i <= 100; i++) {
System.out.print("Factors of " + i + " is: ");
for (int j = 2; j < i; j++) {
if (i % j == 0) System.out.print(j + " ");
}
System.out.println();
}
I was just trying to get the factors of numbers from 2 to 100 but how can i make the inner loop more efficient?
It's a little bit number theory involved here but if you do this it would be efficient specially when the 100 is replaced with something much bigger:
for (int i = 2; i <= 100; i++) {
System.out.print("Factors of " + i + " is: ");
for (int j = 2; j <= (int) Math.sqrt(i); j++) {
if (i % j == 0) System.out.print(j + " " + i / j + " ");
}
System.out.println();
}
You could use the fact that for every divisor a of i there is a number b such that a * b = i.
Find all divisors a <= sqrt(i) and save b = i/a and print these values later.
final int num = 100;
int[] divisors = new int[(int) Math.sqrt(num)];
for (int i = 2; i <= num; i++) {
System.out.print("Factors of " + i + " is: ");
int j = 2;
int index = 0;
for (; j * j < i; j++) {
if (i % j == 0) {
System.out.print(j + " ");
divisors[index++] = i / j;
}
}
if (j * j == i) {
// print sqrt(i) only once, if it's integral
System.out.print(j + " ");
}
while (--index >= 0) {
System.out.print(divisors[index] + " ");
}
System.out.println();
}
This way your inner loop needs only O(sqrt(i)) instead of O(i) operations.
This code time complexity is O(N2).
public static void main(String[] args) {
for (int i = 2; i <= 100; i++) {
System.out.print("Factors of " + i + " is: ");
for (int j = i/2; j > 1; j--) {
if (i % j == 0) System.out.print(j + " ");
}
System.out.println();
}
}
Try this,as your code output will be displayed as follows (ascending order)
Factors of 24 is: 2 3 4 6 8 12
please be noticed, but this given code will be displayed output as follows (descending order )
Factors of 24 is: 12 8 6 4 3 2

Program to generate a matrix defined by user in java

guys!
First of all, I'm from Brazil, so sorry if I make some grammar error.
I'm having problems to solve an exercise in whitch I have to a program that generates a matix in java with user-informed dimensions. Then, it has to fill the matrix with values ​​which are also entered by the user. My code stops of running in my second for, passing by the columns. I get a ArrayIndexOutOfBoundException. Can you help me to see what I'm doing wrong?
import java.util.Scanner;
public class DiagonalsSum {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int[][] matrix;
int[] sizes = new int[2];
int diagonalsSum = 0, i, j, n, m;
for(i = 0; i < 2; i++){
n = i + 1;
System.out.println("Inform the " + n + " dimension of the matrix");
sizes[i] = s.nextInt();
}
matrix = new int[sizes[0]][sizes[1]];
for(i = 0; i < matriz.length; i++){
n = i + 1;
System.out.println(n);
for(j = 0; j < matrix[sizes[0]].length; j++){
m = j = 1;
System.out.println("Inform the value of " + n + "." + m +
" in the matrix:");
matrix[i][j] = s.nextInt();
}
}
s.close();
i = 0;
j = 0;
while(i < matrix.length && j < matrix[sizes[1]].length){
diagonalsSum += matrix[i][j];
i++;
j++;
}
i = 0;
j = (matrix[sizes[i]].length - 1);
while(i < matrix.length && j > 0){
diagonalsSum += matrix[i][j];
i++;
j--;
}
System.out.println("The sum of the primary and secondary diagonals is " + diagonalsSum);
}
Thanks in advance, guys!
Try this:
for(i = 0; i < matrix.length; i++){
matrix[i] = new int[sizes[1]];
n = i + 1;
System.out.println(n);
for(j = 0; j < matrix[sizes[0]].length; j++){
m = j = 1;
System.out.println("Inform the value of " + n + "." + m +
" in the matrix:");
matrix[i][j] = s.nextInt();
}
}
Java's an object-oriented language. You'll do better if you encapsulate the behavior you need in a proper Matrix class.
I think there are a couple of errors in here, but I'll address the one you've asked about.
I believe
for(j = 0; j < matrix[sizes[0]].length; j++)
will always result in going out of bounds because you've declared:
matrix = new int[sizes[0]][sizes[1]];
Note that Java has 0 based indexing, meaning that for any array, array[array.length] will be out of bounds. This type of access is effectively what your for loop is doing.
for(j = 0; j < matrix[sizes[0]-1].length; j++)
should fix the column loop issue.
guys!
I changed some things and it worked!
Thanks for all the help!
import java.util.Scanner;
public class DiagonalsSum {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int[][] matrix;
int[] sizes = new int[2];
int diagonalsSum = 0, i, j, n, m;
for(i = 0; i < 2; i++){
n = i + 1;
System.out.println("Inform the " + n + " dimension of the matrix");
sizes[i] = s.nextInt();
}
matrix = new int[sizes[0]][sizes[1]];
for(i = 0; i < sizes[0]; i++){
n = i + 1;
System.out.println(n);
for(j = 0; j < sizes[1]; j++){
m = j = 1;
System.out.println("Inform the value of " + n + "." + m +
" in the matrix:");
matrix[i][j] = s.nextInt();
}
}
s.close();
i = 0;
j = 0;
while(i < sizes[0] && j sizes[1]){
diagonalsSum += matrix[i][j];
i++;
j++;
}
i = 0;
j = (sizes[1] - 1);
while(i < sizes[0] && j > -1){
diagonalsSum += matrix[i][j];
i++;
j--;
}
System.out.println("The sum of the primary and secondary diagonals is " + diagonalsSum);
}

Bellman Ford detecting negative cycle of shortest length

Solving this Arbitage problem of UVA http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=40 but I am stuck with finding the negative cycle of shortest length(length here is number of vertices).Here is my code that successfully detects the negative cycle
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class _104 {
public static void main(String[] args) throws NumberFormatException,
IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
String input;
while ((input = reader.readLine()) != null) {
int n = Integer.parseInt(input);
double[][] cost = new double[n + 1][n + 1];
double[] spEstimate = new double[n + 1];
int parent[] = new int[n + 1];
for (int i = 0; i < n + 1; i++) {
spEstimate[i] = Double.MAX_VALUE;
cost[0][i] = 0;
cost[i][0] = Double.MAX_VALUE;
parent[i] = Integer.MAX_VALUE;
}
spEstimate[0] = 0.0;
parent[0] = 0;
for (int i = 1; i < n + 1; i++) {
String[] line = reader.readLine().split("\\s+");
for (int j = 1; j < n + 1; j++) {
if (i == j) {
cost[i][j] = 0;
} else if (i < j) {
cost[i][j] = -(Math
.log(Double.parseDouble(line[j - 2])) / Math
.log(2));
} else {
cost[i][j] = -(Math
.log(Double.parseDouble(line[j - 1])) / Math
.log(2));
}
}
}
int save = 1, s = 1;
boolean flag = BellmanFord(n, cost, spEstimate, parent);
display(cost);
// Relax all edges once more
boolean brk = true;
for (int i = 0; i < cost.length && brk; i++) {
for (int j = 0; j < cost.length && brk; j++) {
//relax(i, j, spEstimate, cost[i][j], parent);
}
}
ArrayList<Integer> path = new ArrayList<Integer>();
while (parent[save] != s) {
path.add(save);
save = parent[save];
}
if (flag) {
System.out.println("no arbitrage sequence exists");
} else {
path.add(0, path.get(path.size() - 1));
for (int i = path.size() - 1; i >= 0; --i) {
System.out.println(path.get(i));
}
}
}
reader.close();
}
public static boolean BellmanFord(int n, double[][] cost, double[] sp,
int[] parent) {
for (int k = 0; k < n - 1; k++) {
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost.length; j++) {
relax(i, j, sp, cost[i][j], parent);
}
}
}
// Relax all edges once more to detect cycle
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost.length; j++) {
if (sp[j] > (sp[i] + cost[i][j])) {
return false;
}
}
}
return true;
}
static void relax(int i, int j, double[] sp, double cij, int[] parent) {
if (sp[j] > (sp[i] + cij)) {
sp[j] = sp[i] + cij;
System.out.println("relaxed " + i + " " + j + " " + cij + " "
+ sp[i] + " " + sp[j]);
parent[j] = i;
}
}
static void display(double[][] cost) {
System.out.println("Display Cost");
for (int i = 0; i < cost.length; i++) {
for (int j = 0; j < cost.length; j++) {
System.out.print(cost[i][j] + "\t");
}
System.out.println();
}
}
static void display(double[] sp) {
for (int i = 0; i < sp.length; i++) {
System.out.println(sp[i]);
}
}
}
You can do it like that:
Fix the start vertex of the cycle(let's call it v).
Run Ford-Bellman algorithm assuming that dist[i] = 0 if i = v and INF otherwise.
If there is a negative cycle that contains v, after k iterations of the outer loop in Ford-Bellman algorithm dist[v] will become negative. So you can easily find such smallest k by simply checking if dist[v] is still non-negative or not after each iteration.
The smallest k among all v is the answer.
It is possible to solve this problem by considering cycles of increasing length as opposed to finding negative cycles as described by kraskevich. The worst case complexity for both approaches is O(n^4). This approach resembles Floyd-Warshall where you consider increasing lengths instead of intermediate vertices.
You can find a detailed explanation that includes diagrams and code here.

go to beginning of for statement in java

I'm very new to Java and maybe my question is a bit irritating.
I have two for loops in my code and I want to go to the beginning of each one by a for-else statement.
public static void main(String[] args)
{
int[][] x=new int[1000][1000];
int[] Z=new int[1000];
lable1:
for(int i=1; i<=1000; i++)
{
Z[i]=rand1.nextInt(1000);
System.out.println("Z["+i +"] = " + Z[i] );
if(Z[i]>0 && Z[i]<=Nk)
{
int Z1=Z[i]-1;
lable2:
for(int j = 1; j<=Z1;j++ )
{
x[i][j]= rand2.nextInt(1000);
sum+=x[i][j];
if( sum<1000)
{
x[i][(j+1)]=1000-sum;
System.out.println("x[" + i+"][" + j + "] = " + x[i][j]);
System.out.println("Nx[" + i+"][" + (j+1) + "] = " +x[i][(j+1)]);
}
else{
// ????
//Goto lable2;
}
}
}
else{
//goto label1;
// ????
}
}
}
You can break to any defined label (within scope) by using:
break label;
Same holds for continue.
Here is something to read.
In your particular example, removing the elses would do what you want.
Just use continue keyword.. It will continue with the next iteration.. No need to label your loop.. As you are not continuing the outer loop from the inner one.. Or, if you want to continue with outer loop, you can use continue with a label...
And you should use your for loop from j = 0 to j < z1..
for(int j = 0; j < Z1;j++ ) {
if( sum<1000) {
x[i][(j+1)]=1000-sum;
System.out.println("x[" + i+"][" + j + "] = " + x[i][j]);
System.out.println("Nx[" + i+"][" + (j+1) + "] = " +x[i][(j+1)]);
}
else{ // Not needed if your else does not contain anything else..
continue;
}
}
In fact you don't need an else block at all.. If you are not doing any further processing in it..
Just remove it.. It will automatically go to your loop..
Suggestion: - You should use coding convention.. variable names start with lowercase letter or underscore.. (Z1 -> z1)
Here you are:
public static void main(String[] args) {
int[][] x = new int[1000][1000];
int[] Z = new int[1000];
boolean resetOuterCycle = true;
for (int i = 0; i < 1000; i++) {
Z[i] = rand1.nextInt(1000);
System.out.println("Z[" + i + "] = " + Z[i]);
if (Z[i] > 0 && Z[i] <= Nk) {
int Z1 = Z[i] - 1;
boolean resetInnerCycle = true;
for (int j = 0; j < Z1; j++) {
x[i][j] = rand2.nextInt(1000);
sum += x[i][j];
if (sum < 1000) {
x[i][(j + 1)] = 1000 - sum;
System.out.println("x[" + i + "][" + j + "] = " + x[i][j]);
System.out.println("Nx[" + i + "][" + (j + 1) + "] = " + x[i][(j + 1)]);
} else if (resetInnerCycle) {
j = 0;
resetInnerCycle = false;
}
}
} else if (resetOuterCycle) {
i = 0;
resetOuterCycle = false;
}
}
}
- In your above code you can use 2 approach to do it...
1st Approach : No else part
for (int i = 0; i < 1000; i++) {
if (Z[i] > 0 && Z[i] <= Nk){
for (int j = 0; j < Z1; j++) {
if(sum < 1000){
}
}
}
}
2nd Approach : With else part and continue
for (int i = 0; i < 1000; i++) {
if (Z[i] > 0 && Z[i] <= Nk){
for (int j = 0; j < Z1; j++) {
if(sum < 1000){
}else{
continue;
}
}
}else{
continue;
}
}

Categories

Resources