Error when setting entry of int[] array to null - java

I had the following idea to take an array and remove any duplicates. However, I am getting the error "error: incompatible types: cannot be converted to int" referring to the part of the code where I set temp[i] = null. Is it possible to do this? How can I fix this problem?
public static int[] withoutDuplicates(int[] x) {
int[] temp = new int[x.length];
int count = 0;
for (int i = x.length - 1; i >= 0; i--) {
for (int j = i-1; j >= 0; j--) {
if (temp[i] == x[j]) {
temp[i] = null;
count++;
}
}
}
int size = x.length - count;
int[] a = new int[size];
int pos = 0;
for (int i = 0; i < x.length; i++) {
if (temp[i] != null) {
a[pos] = temp[i];
pos++;
}
}
return a;
}

Stream-based solution is concise but for your task/requirements you could be using just a temporary boolean array to mark positions of duplicates:
public static int[] withoutDuplicates(int[] x) {
boolean[] duplicated = new boolean[x.length];
int count = 0;
for (int i = x.length - 1; i > 0; i--) {
for (int j = i-1; j >= 0; j--) {
if (x[i] == x[j]) {
duplicated[i] = true;
count++;
}
}
}
int size = x.length - count;
int[] a = new int[size];
for (int i = 0, pos = 0; pos < size && i < x.length; i++) {
if (!duplicated[i]) {
a[pos++] = x[i];
}
}
return a;
}
Test:
int[] arr1 = {1, 2, 3, 4, 3, 5, 2};
int[] arr2 = {1, 2, 3, 4, 0, 5, 6};
System.out.println(Arrays.toString(withoutDuplicates(arr1)));
System.out.println(Arrays.toString(withoutDuplicates(arr2)));
output
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 0, 5, 6]

You can't assign a null to a primitive type int but you can assign a null to the wrapper object Integer.
To remove the duplicates of an int array you could use something like this:
myIntArray = Arrays.stream(myIntArray).distinct().toArray();

Related

Delete local maximum

A local maximum is an element that is greater than any of its neighboring elements. You must remove elements that are local maxima in the original array.
Input array:
[18, 1, 3, 6, 7, -5]
output array:
[1, 3, 6, -5]
public static int[] removeLocalMaxima(int[] array){
int[] result = new int[array.length];
int j = 0;
for (int i = 0; i < array.length - 1; i++, j++) {
if(array[i] > array[i + 1]){
result[j] = array[++i];
}else {
result[j] = array[i];
}
}
return Arrays.copyOf(result, j);
}
if you set it like that, then something is not working:
array = new int[1000];
Arrays.fill(array, 15);
array[0] = -20;
array[999] = 25;
array[168] = 18;
array[421] = 0;
actual = LocalMaximaRemove.removeLocalMaxima(array);
assertEquals(998, actual.length);
assertEquals(-20, actual[0]);
assertEquals(15, actual[997]);
assertEquals(0, actual[420]);
public static int[] removeLocalMaxima(int[] array){
int[] result = new int[array.length];
int j = 0;
for (int i = 0; i < array.length; i++) {
if ((i > 0 && array[i] <= array[i - 1])
|| (i != array.length - 1 && array[i] <= array[i + 1])){
result[j++] = array[i];
}
}
return Arrays.copyOf(result, j);
}
My function saves in result array only elements that are less or equal of any of its neightbors.

Java Program for Displaying Numbers in Array 1 not in Array 2

I'm looking to make a code that will display unique numbers in array x not in array y. This is what I have so far. What am I doing wrong?
int unique=0;
int i,j,k;
int x[]={1,2,3,4,5};
int y[]={1,3,5,7,9};
for(i=0;i<x.length;i++)
{
for(j=0;j<y.length;j++)
{
if(x[i] == y[j])
{
unique = 1;
}
}
if(unique == 0)
{
System.out.print(x[i]);
unique =0;
}
}
The code is producing 000011111222233334444.
I think you should reset the unique value. So just add unique = 0; at the endo of the first loop:
int unique = 0;
int i, j, k;
int x[] = {1, 2, 3, 4, 5};
int y[] = {1, 3, 5, 7, 9};
for (i = 0; i < x.length; i++) {
for (j = 0; j < y.length; j++) {
if (x[i] == y[j]) {
unique = 1;
}
}
if (unique == 0) {
System.out.print(x[i]);
unique = 0;
}
unique = 0;
}

My Array merge sorter does not work properly with odd number length of the array that includes some duplicate values

My Array merge sorter does not work properly with odd number length of the array that includes some duplicate values. For example, for int[] array = {1, 3, 15, 3, 7, 9, 8, 15, 0} the result is {0, 1, 3, 3, 7, 8, 0, 9, 15,}. Can someone tell me where I am wrong?
public static void mergeSort(int[] inputArray) {
int size = inputArray.length;
if (size < 2)
return;
int mid = size / 2;
int leftSize = mid;
int[] left = Arrays.copyOfRange(inputArray, 0, leftSize);
int[] right = Arrays.copyOfRange(inputArray, leftSize, inputArray.length);
mergeSort(left);
mergeSort(right);
merge(left, right, inputArray);
}
public static void merge(int[] left, int[] right, int[] arr) {
int leftSize = left.length;
int rightSize = right.length;
int i = 0, j = 0, k = 0;
while (i < leftSize && j < rightSize) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
while (i < leftSize) {
arr[k++] = left[i++];
}
while (j < leftSize) {
arr[k++] = right[j++];
}
}
Change this
while (j < leftSize) {
arr[k++] = right[j++];
}
To
while (j < rightSize) {
arr[k++] = right[j++];
}

Remove zeros in an array without creating new method

Im trying to remove zeros from an arrays. I could do a separate method to remove the zeros but i want it in idiomatic way.
public int[] commonFactors(int m, int n) {
int[] numbers = new int[n + 1];
for(int i = 1; i < n + 1; i++) {
if ((m % i == 0) && (n % i == 0)) {
numbers[i] = i;
}
}
return numbers;//or return DelZero(numbers);
}
And here is the method to remove all the zeros:
public int[] DelZero(int numbers[]) {
int zeroCount=0;
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == 0) {
zeroCount++;
}
}
int[] newNumber = new int[numbers.length-zeroCount];
int j =0;
for (int i=0; i<numbers.length; i++) {
if (numbers[i] != 0) {
newNumber[j++] = numbers[i];
}
}
return newNumber;
}
So the crux of my question is this: Is there a way to remove the zeros without creating a new method? (In this case without DelZero.)
With Java8, you can exploit Stream to do it very easily:
int[] arr = new int[]{0,0,7,6,5,0,1,0,4};
int[] arr_without_zeros = IntStream.of(arr).filter(i -> i != 0).toArray();
Here's a quick example from which you should be able to answer your question:
import java.util.Arrays;
public class RemoveZeros {
public static void main(String[] args) {
int[] zeroArray = { 0, 1, 0, 2, 0, 3, 0, 4, 0, 5 };
System.out.println("Original array: " + Arrays.toString(zeroArray));
int nonZeros = 0;
for (int i = 0; i < zeroArray.length; i++) {
if (zeroArray[i] != 0) {
nonZeros++;
}
}
int[] tempArray = new int[nonZeros];
int tempIndex = 0;
for (int j = 0; j < zeroArray.length; j++) {
if (zeroArray[j] != 0) {
tempArray[tempIndex] = zeroArray[j];
tempIndex++;
}
}
zeroArray = tempArray;
System.out.println("Modified array: " + Arrays.toString(zeroArray));
}
}
Output:
Original array: [0, 1, 0, 2, 0, 3, 0, 4, 0, 5]
Modified array: [1, 2, 3, 4, 5]
I'd consider using java.util.List instead of primitive array. Suddenly everything is a lot easier...
public List<Integer> commonFactors(int m, int n) {
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i < n + 1; i++) {
if ((m % i == 0) && (n % i == 0) && i != 0) {
numbers.add(i);
}
}
return numbers;
}

Determinant of huge matrix Java

I am making a project in Java where i have to use BigInteger class to implement an encryption method.
I have square matrices nxn where n can be 200 and i need to calculate the determinant. I did the method using the determinant of submatrices but its taking forever to calculate.
public BigInteger determinant(Matrix matrix){
if (matrix.getColumns()!=matrix.getRows()){
System.out.println("The matrix is not square");
return BigInteger.valueOf(-1);
}
if (matrix.getColumns() == 1) {
return matrix.getMatrix()[0][0];
}
if (matrix.getRows()==2) {
return ((matrix.getValueAt(0, 0).multiply(matrix.getValueAt(1, 1)))).subtract(( matrix.getValueAt(0, 1).multiply(matrix.getValueAt(1, 0))));
}
BigInteger sum = BigInteger.valueOf(0);
for (int i=0; i<matrix.getColumns(); i++) {
sum = sum.add(this.changeSign(BigInteger.valueOf(i)).multiply(matrix.getValueAt(0, i)).multiply(determinant(createSubMatrix(matrix, 0, i))));// * determinant(createSubMatrix(matrix, 0, i));
}
return sum;
}
Is there a non-recursive way to calculate the determinant?
Thanks in advance.
I've posted this as a comment but I think this could actually solve your problem so I'm posting it as an answer as well.
You can use this package: http://math.nist.gov/javanumerics/jama/
A common practice of calculating the deterninat of huge matrices is the use an LUP decomposition. In this case, the decerminant can be calculated with following ideas:
{L, U, P} = LUP(A)
sign = -1 ^ 'number of permutations in P'
det(A) = diagonalProduct(U) * sign
This is how big math packages do that. You should probably implement LU by yourself.
I believe this is exactly what you need.Using This class you can calculate the determinant of a matrix with any dimension
This class uses many different methods to make the matrix triangular and then, calculates the determinant of it. It can be used for matrix of high dimension like 500 x 500 or even more. the bright side of the this class is that you can get the result in BigDecimal so there is no infinity and you'll have always the accurate answer. By the way, using many various methods and avoiding recursion resulted in much faster way with higher performance to the answer. hope it would be helpful.
import java.math.BigDecimal;
public class DeterminantCalc {
private double[][] matrix;
private int sign = 1;
DeterminantCalc(double[][] matrix) {
this.matrix = matrix;
}
public int getSign() {
return sign;
}
public BigDecimal determinant() {
BigDecimal deter;
if (isUpperTriangular() || isLowerTriangular())
deter = multiplyDiameter().multiply(BigDecimal.valueOf(sign));
else {
makeTriangular();
deter = multiplyDiameter().multiply(BigDecimal.valueOf(sign));
}
return deter;
}
/* receives a matrix and makes it triangular using allowed operations
on columns and rows
*/
public void makeTriangular() {
for (int j = 0; j < matrix.length; j++) {
sortCol(j);
for (int i = matrix.length - 1; i > j; i--) {
if (matrix[i][j] == 0)
continue;
double x = matrix[i][j];
double y = matrix[i - 1][j];
multiplyRow(i, (-y / x));
addRow(i, i - 1);
multiplyRow(i, (-x / y));
}
}
}
public boolean isUpperTriangular() {
if (matrix.length < 2)
return false;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < i; j++) {
if (matrix[i][j] != 0)
return false;
}
}
return true;
}
public boolean isLowerTriangular() {
if (matrix.length < 2)
return false;
for (int j = 0; j < matrix.length; j++) {
for (int i = 0; j > i; i++) {
if (matrix[i][j] != 0)
return false;
}
}
return true;
}
public BigDecimal multiplyDiameter() {
BigDecimal result = BigDecimal.ONE;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
if (i == j)
result = result.multiply(BigDecimal.valueOf(matrix[i][j]));
}
}
return result;
}
// when matrix[i][j] = 0 it makes it's value non-zero
public void makeNonZero(int rowPos, int colPos) {
int len = matrix.length;
outer:
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
if (matrix[i][j] != 0) {
if (i == rowPos) { // found "!= 0" in it's own row, so cols must be added
addCol(colPos, j);
break outer;
}
if (j == colPos) { // found "!= 0" in it's own col, so rows must be added
addRow(rowPos, i);
break outer;
}
}
}
}
}
//add row1 to row2 and store in row1
public void addRow(int row1, int row2) {
for (int j = 0; j < matrix.length; j++)
matrix[row1][j] += matrix[row2][j];
}
//add col1 to col2 and store in col1
public void addCol(int col1, int col2) {
for (int i = 0; i < matrix.length; i++)
matrix[i][col1] += matrix[i][col2];
}
//multiply the whole row by num
public void multiplyRow(int row, double num) {
if (num < 0)
sign *= -1;
for (int j = 0; j < matrix.length; j++) {
matrix[row][j] *= num;
}
}
//multiply the whole column by num
public void multiplyCol(int col, double num) {
if (num < 0)
sign *= -1;
for (int i = 0; i < matrix.length; i++)
matrix[i][col] *= num;
}
// sort the cols from the biggest to the lowest value
public void sortCol(int col) {
for (int i = matrix.length - 1; i >= col; i--) {
for (int k = matrix.length - 1; k >= col; k--) {
double tmp1 = matrix[i][col];
double tmp2 = matrix[k][col];
if (Math.abs(tmp1) < Math.abs(tmp2))
replaceRow(i, k);
}
}
}
//replace row1 with row2
public void replaceRow(int row1, int row2) {
if (row1 != row2)
sign *= -1;
double[] tempRow = new double[matrix.length];
for (int j = 0; j < matrix.length; j++) {
tempRow[j] = matrix[row1][j];
matrix[row1][j] = matrix[row2][j];
matrix[row2][j] = tempRow[j];
}
}
//replace col1 with col2
public void replaceCol(int col1, int col2) {
if (col1 != col2)
sign *= -1;
System.out.printf("replace col%d with col%d, sign = %d%n", col1, col2, sign);
double[][] tempCol = new double[matrix.length][1];
for (int i = 0; i < matrix.length; i++) {
tempCol[i][0] = matrix[i][col1];
matrix[i][col1] = matrix[i][col2];
matrix[i][col2] = tempCol[i][0];
}
}
}
And then this class receives a matrix of n x n from the user or can generate a random matrix of nxn and then calculates it's determinant. It also shows the solution and the final triangular matrix.
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.text.NumberFormat;
import java.util.Scanner;
public class DeterminantTest {
public static void main(String[] args) {
String determinant;
//generating random numbers
int len = 500;
SecureRandom random = new SecureRandom();
double[][] matrix = new double[len][len];
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
matrix[i][j] = random.nextInt(500);
System.out.printf("%15.2f", matrix[i][j]);
}
}
System.out.println();
/*double[][] matrix = {
{1, 5, 2, -2, 3, 2, 5, 1, 0, 5},
{4, 6, 0, -2, -2, 0, 1, 1, -2, 1},
{0, 5, 1, 0, 1, -5, -9, 0, 4, 1},
{2, 3, 5, -1, 2, 2, 0, 4, 5, -1},
{1, 0, 3, -1, 5, 1, 0, 2, 0, 2},
{1, 1, 0, -2, 5, 1, 2, 1, 1, 6},
{1, 0, 1, -1, 1, 1, 0, 1, 1, 1},
{1, 5, 5, 0, 3, 5, 5, 0, 0, 6},
{1, -5, 2, -2, 3, 2, 5, 1, 1, 5},
{1, 5, -2, -2, 3, 1, 5, 0, 0, 1}
};
double[][] matrix = menu();*/
DeterminantCalc deter = new DeterminantCalc(matrix);
BigDecimal det = deter.determinant();
determinant = NumberFormat.getInstance().format(det);
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
System.out.printf("%15.2f", matrix[i][j]);
}
System.out.println();
}
System.out.println();
System.out.printf("%s%s%n", "Determinant: ", determinant);
System.out.printf("%s%d", "sign: ", deter.getSign());
}
public static double[][] menu() {
Scanner scanner = new Scanner(System.in);
System.out.print("Matrix Dimension: ");
int dim = scanner.nextInt();
double[][] inputMatrix = new double[dim][dim];
System.out.println("Set the Matrix: ");
for (int i = 0; i < dim; i++) {
System.out.printf("%5s%d%n", "row", i + 1);
for (int j = 0; j < dim; j++) {
System.out.printf("M[%d][%d] = ", i + 1, j + 1);
inputMatrix[i][j] = scanner.nextDouble();
}
System.out.println();
}
scanner.close();
return inputMatrix;
}
}
The recursive method will take ages to find the determinant of the Matrix of dimension more than 10x10. You will need to do LU decomposition and Gaussian reduction. I used this to find a determinant of 1000x1000 matrix and it produced the correct result within a sec.
You can get this code in Numerical Recipes Book ( use 3rd edition only ): line 52. It is written in C++ but you can easily convert it in Java
or else check ludcmp() in this
https://www.cc.gatech.edu/gvu/people/Phd/warren/matrix.c

Categories

Resources