I'm working on an arraylist implementation of PrimeSieve and I have all the code written but it seems to not run so I'm not sure if it's because the loops are bad or because I set up the scanner wrong.
Here's the code.
import java.util.Scanner;
import java.util.ArrayList;
public class PrimeSieve {
public static void main(String[] args)
{
int inputNum;
Scanner SL = new Scanner(System.in);
System.out.print("Pick a number to count up from:");
inputNum = SL.nextInt();
ArrayList<Boolean> BL = findPrime(inputNum);
System.out.println("The prime numbers found:");
for(int i = 0; i < inputNum; i++)
{
if(BL.get(i) == true)
{
System.out.println(i + ", ");
}
}
}
public static ArrayList<Boolean> findPrime(int maxNum)
{
ArrayList<Boolean> BL = new ArrayList<Boolean>();
//Filling in the list.
for(int i = 0; i < maxNum; i++)
{
BL.add(true);
}
for(int i = 0; i * i <(maxNum); i++)
{
if(BL.get(i) == true)
{
for(int k = i*2; k < maxNum; k = k + i)
{
BL.set(i, false);
}
}
}
return BL;
}
}
Once I input any number and press enter, nothing works. My assumption would be that the program is constantly looping somewhere and it has to be broken.
You have neverending for loop here:
for(int k = i*2; k < maxNum; k = k + i)
i is 0 and k is 0 so every step k=0+0
There is your problem:
for (int i = 0; i * i < (maxNum); i++) {
if (BL.get(i) == true) {
for (int k = i * 2; k < maxNum; k = k + i) {
BL.set(i, false);
}
}
}
First iteraction ( i = 0 ) :
for (int k = 0 * 2; k < maxNum; k = k + 0)
its like :
for (int k = 0 ; k < X ; k = k + 0 )
Fix it :)
About your problem ... it's easy guy ( use debug :) ):
for (int i = 2; i * i < (maxNum); i++) {
if (BL.get(i) == true) {
for (int k = i * 2; k < maxNum; k = k + i) {
BL.set(k, false);
}
}
}
Changes :
int i = 2;
and
BL.set(k,false);
You must learn it by yourself :(
Related
I need the maximum elements position if there is more than one maximum element then the first one is to be printed.
My code prints the position of the maximum element but not the first one.
I don't understand why the last iteration is not working as I intend it to.
Please solve it using only Java.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
// put your code here
Scanner sc = new Scanner(System.in);
// define lengths
int n = sc.nextInt();
int m = sc.nextInt();
// add length to matrix
int[][] matrix = new int[n][m];
// insert elements
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
matrix[i][j] = sc.nextInt();
}
}
// define max
int max = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] > max) {
max = matrix[i][j];
}
}
// System.out.print(i + " " + j);
}
// System.out.print(max + " ");
// print index of highest element
// int pos1 = 0;
// int pos2 = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (matrix[i][j] == max) {
System.out.print(i + " " + j);
break;
}
// pos2 += 1;
break;
}
// pos1 += 1;
// break;
}
}
}
There is no need to go through the matrix twice. When you are searching for the max, store also the coordinates of the matrix where that max was found. A code example:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
// put your code here
Scanner sc = new Scanner(System.in);
// define lengths
int n = sc.nextInt();
int m = sc.nextInt();
// add length to matrix
int[][] matrix = new int[n][m];
// insert elements
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
matrix[i][j] = sc.nextInt();
}
}
// define max
int max = Integer.MIN_VALUE, row=0, col=0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] > max) {
max = matrix[i][j];
row=i;
col=j;
}
}
}
System.out.print("max: "+max + " is at: ");
System.out.print(col + " " + row); //indexes starting from zero
}
}
Create a new variable to hold the position of the max value and set it in the current loop
int max = matrix[0][0];
int[] maxPos = new int[2];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] > max) {
max = matrix[i][j];
maxPos[0] = i;
maxPos[1] = j;
}
}
}
and then remove the rest of the code and print the result
System.out.printf("Max is %d and is found at [%d, %d]\n", max, maxPos[0], maxPos[1]);
Given the number n, not exceeding 10, and a matrix of size n × n.
Check whether this matrix is symmetric in relation to the main diagonal. Output the word “YES”, if it is symmetric and the word “NO” otherwise.
This is my code, it unfortunately does not work. Please, explain to me how to do it correctly :)
public class Main { public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n= scanner.nextInt();
int[][] number = new int[n][n];
boolean ismatch = false;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
number[i][j] = scanner.nextInt();
}
}
int unevenchecker = (n% 2);
if (unevenchecker != 0) {
for (int k = 0; k < number.length - 1; k++) {
for (int l = 0; l < number.length - 1; l++) {
if (number[k][l] == number[l][k]) {
ismatch = true;
}
}
}
if (ismatch) {
System.out.print("YES");
}
} else {
System.out.print("NO");
}
}
}
The matrix is not symmetric if you find at least 1 symmetric couple where the 2 parts are not equal, so instead of checking for equality inside the loop, check for inequality:
ismatch = true;
for (int k = 0; k < number.length - 1; k++) {
for (int l = 0; l < number.length - 1; l++) {
if (number[k][l] != number[l][k]) {
ismatch = false;
break;
}
}
}
public class Main {
static boolean isSymmetric(int mat[][], int size) {
for (int i = 0; i < size; i++)
for (int j = i + 1; j < size - i; j++)
if (mat[i][j] != mat[j][i])
return false;
return true;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n= scanner.nextInt();
int[][] number = new int[n][n];
boolean ismatch = false;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
number[i][j] = scanner.nextInt();
}
}
if (isSymmetric(number, n)) {
System.out.print("YES");
} else {
System.out.print("NO");
}
}
}
Notice that the nested loop into isSymmetric starts from j = i + 1, for not checking twice same condition.
I want to get a number from user and calculate how many different triangles can be formed with the given length for example :
5 (2-2-1)
Answer: 1
12 (5,5,2)(3,4,5)(4,4,4)
Answer: 3
I've wrote some codes but I want a faster way to do that.
Here is my codes:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int t = input.nextInt();
int value = 0;
for (int i = 1; i < t; i++) {
for (int j = i; j < t; j++) {
for (int h = j; h < t; h++) {
if (i+h+j == t & i+j > h & i+h > j & h+j > i) value++;
}
}
}
System.out.println(value);
}
You can do it in O(1):
int n = input.nextInt();
long value = Math.round(((long)n*n)/12d) - ((long)n/4)*(((long)n + 2)/4);
using Alcuin's Sequence.
You can make it O(n^2) easily.
for (int i = 1; i < t; i++) {
for (int j = i; j < t; j++) {
int h=t-i-j;
//check in O(1)
}
}
I am doing a solution to a coding problem, and I tweaked some existing code to be able to figure out how many semi-primes exist up till and including a certain number.
However, I am stuck at the part where I want to count the number of unique semi-primes between two numbers e.g. 10 and 4, which would be 4,6,9 and 10, i.e. 4. My answer is simply saying 10 has 4 semi-primes, 4 has 1 semi-primes, so the sub-primes between them are 4-1 =3. This is where I am going wrong.
Code is here:
public class SemiPrimeRange {
public static int[] solution(int N, int[] P, int[] Q) {
int arrSize = P.length;
int[] arr = new int[arrSize];
for (int i = 0; i < arr.length; i++) {
int n = NoSemiPrimes(Q[i]);
int m = NoSemiPrimes(P[i]);
arr[i] = n-m;
}
for (int i : arr) {
System.out.println(i);
}
return arr;
}
public static int NoSemiPrimes(int large) {
int n = 0;
boolean[] primeTop = new boolean[large + 1];
boolean[] semiprimeTop = new boolean[large + 1];
for (int i = 2; i <= large; i++) {
primeTop[i] = true;
}
for (int i = 2; i * i <= large; i++) {
if (primeTop[i]) {
for (int j = i; i * j <= large; j++) {
primeTop[i * j] = false;
}
}
}
int primes = 0;
for (int i = 2; i <= large; i++) {
if (primeTop[i])
primes++;
}
for (int i = 0; i < large; i++) {
semiprimeTop[i] = false;
}
for (int i = 0; i <= large; i++) {
for (int j = i; j <= large; j++) {
if (primeTop[j]&&primeTop[i]) {
if(i*j<=large){
semiprimeTop[j*i] = true;
}
}
}
}
for (int i = 0; i < semiprimeTop.length; i++) {
System.out.println(semiprimeTop[i]);
}
int semiprimes = 0;
for (int i = 2; i <= large; i++) {
if (semiprimeTop[i])
semiprimes++;
}
System.out.println("The number of semiprimes <= " + large + " is " + semiprimes);
return semiprimes;
}
public static void main(String[] args) {
int[] P = { 1, 4, 16 };
int[] Q = { 26, 10, 20 };
int N = 26;
solution(N, P, Q);
}
If you want number of semi-primes between y and x (y > x), count(y) - count(x) (count(a) is number of semi-primes between a and 1) is not a correct formula because it will omit x if it is semi-prime. Correct formula is count(y) - count(x - 1).
Also note that your code is ineffective because it will count between 1 and the lesser number twice.
The method signature should be
public static int NoSemiPrimes(int small, int large)
and change the loop
int semiprimes = 0;
for (int i = 2; i <= large; i++) {
if (semiprimeTop[i])
semiprimes++;
}
to
int semiprimes = 0;
for (int i = small; i <= large; i++) {
if (semiprimeTop[i])
semiprimes++;
}
to count the number of semi-primes in desired range directly instead of using int NoSemiPrimes(int large) twice.
With n=5 and k=3 the following loop will do it
List<String> l=new ArrayList<String>();
l.add("A");l.add("B");l.add("C");l.add("D");l.add("E");
int broadcastSize = (int) Math.pow(2, l.size());
for (int i = 1; i < broadcastSize; i++) {
StringBuffer buffer = new StringBuffer(50);
int mask = i;
int j = 0;
int size=0;
System.out.println();
while (mask > 0) {
if ((mask & 1) == 1) {
System.out.println(".. "+mask);
buffer.append(l.get(j));
if (++size>3){
buffer = new StringBuffer(50);
break;
}
}
System.out.println(" "+mask);
mask >>= 1;
j++;
}
if (buffer.length()>0)
System.out.println(buffer.toString());
}
but it's not efficient I would like to do it with Banker's sequence and thus explore first singletons, then pairs, then 3-tuple and stop.
I did not find a way do that, but at least this loop should be more efficient:
List<String> l=new ArrayList<String>();
l.add("A");l.add("B");l.add("C");l.add("D");l.add("E");
int broadcastSize = (int) Math.pow(2, l.size());
for (int i = 1; i < broadcastSize; i++) {
StringBuffer buffer = new StringBuffer(50);
int mask = i;
int j = 0;
if (StringUtils.countMatches(Integer.toBinaryString(i), "1") < 4){
while (mask > 0) {
if ((mask & 1) == 1) {
buffer.append(l.get(j));
}
mask >>= 1;
j++;
}
if (buffer.length()>0)
System.out.println(buffer.toString());
}
}
there is also: but k embedded loops looks ugly
//singleton
for (int i = 0; i < l.size(); i++) {
System.out.println(l.get(i));
}
//pairs
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
System.out.println(l.get(i)+l.get(j));
}
}
//3-tuple
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
for (int k = j+1; k < l.size(); k++) {
System.out.println(l.get(i)+l.get(j)+l.get(k));
}
}
}
//...
// k-tuple
This technique is called Gosper's hack. It only works for n <= 32 because it uses the bits of an int, but you can increase it to 64 if you use a long.
int nextCombo(int x) {
// moves to the next combination with the same number of 1 bits
int u = x & (-x);
int v = u + x;
return v + (((v ^ x) / u) >> 2);
}
...
for (int x = (1 << k) - 1; (x >>> n) == 0; x = nextCombo(x)) {
System.out.println(Integer.toBinaryString(x));
}
For n = 5 and k = 3, this prints
111
1011
1101
1110
10011
10101
10110
11001
11010
11100
exactly as you'd expect.
this should be the most efficient way, even if k embedded loops looks ugly
//singleton
for (int i = 0; i < l.size(); i++) {
System.out.println(l.get(i));
}
//pairs
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
System.out.println(l.get(i)+l.get(j));
}
}
//3-tuple
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
for (int k = j+1; k < l.size(); k++) {
System.out.println(l.get(i)+l.get(j)+l.get(k));
}
}
}
// ...
//k-tuple
Apache commons has iterators for subsets of size k, and for permutations.
Here is an iterator that iterates through 1-k tuples of an n-tuple, that combines the two:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.collections4.iterators.PermutationIterator;
import org.apache.commons.math3.util.Combinations;
public class AllTuplesUpToKIterator implements Iterator<List<Integer>> {
private Iterator<int[]> combinationIterator;
private PermutationIterator<Integer> permutationIterator;
int i;
int k;
int n;
public AllTuplesUpToKIterator(int n, int k) {
this.i = 1;
this.k = k;
this.n = n;
combinationIterator = new Combinations(n, 1).iterator();
permutationIterator = new PermutationIterator<Integer>(intArrayToIntegerList(combinationIterator.next()));
}
#Override
public boolean hasNext() {
if (permutationIterator.hasNext()) {
return true;
} else if (combinationIterator.hasNext()) {
return true;
} else if (i<k) {
return true;
} else {
return false;
}
}
#Override
public List<Integer> next() {
if (!permutationIterator.hasNext()) {
if (!combinationIterator.hasNext()) {
i++;
combinationIterator = new Combinations(n, i).iterator();
}
permutationIterator = new PermutationIterator<Integer>(intArrayToIntegerList(combinationIterator.next()));
}
return permutationIterator.next();
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
public static List<Integer> intArrayToIntegerList(int[] arr) {
List<Integer> result = new ArrayList<Integer>();
for (int i=0; i< arr.length; i++) {
result.add(arr[i]);
}
return result;
}
public static void main(String[] args) {
int n = 4;
int k = 2;
for (AllTuplesUpToKIterator iter= new AllTuplesUpToKIterator(n, k); iter.hasNext();) {
System.out.println(iter.next());
}
}
}