counting negative numbers in array - java

I am trying to find the counts for negative numbers in a 2d-array ( square- matix). In matrix if you go from up to down and left to write number increases. Logic here is to start from last column and proceed to the left. If you find the neg num then increase the row index and proceed the same way till the last row. I am getting the error in java code but not in python.
public class O_n
{
public static void main(String[] args)
{
int firstarray[][] = {{-2,-1,0},{-1,0,1},{0,1,2}};
int secondarray[][] = {{-4,-3,-2},{-3,-2,-1},{-2,-1,0}};
System.out.print ("First array has"+count_neg(firstarray));
System.out.println("negative numbers");
System.out.print ("Second array has"+count_neg(secondarray));
System.out.println("negative numbers");
}
public static int count_neg(int x[][]){
int count = 0;
int i = 0; //rows
int j = x.length - 1; //columns
System.out.println("max column index is: "+j);
while ( i >=0 && j<x.length){
if (x[i][j] < 0){ // negative number
count += (j + 1);// since j is an index...so j + 1
i += 1;
}
else { // positive number
j -= 1;
}
}
return (count);
}
}
I am getting this output
max column index is: 2
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at O_n.count_neg(O_n.java:22)
at O_n.main(O_n.java:9)
/home/eos/.cache/netbeans/8.1/executor-snippets/run.xml:53: Java
returned: 1
BUILD FAILED (total time: 0 seconds)
What is wrong with this code? the same thing worked in python...
def count_neg(array):
count = 0
i = 0 # row
j = len(array) -1 # col
# since we are starting from right side
while j >= 0 and i < len(array):
if array[i][j] < 0:
count += (j + 1)
i += 1
else:
j -= 1
return count
print(count_neg([[-4,-3,-1,1],[-2,-2,1,2],[-1,1,2,3],[1,2,4,5]]))

I would write the method like this, just go through the 2d array and increase count each time a negative number is found
public static int count_neg(int x[][]){
int count = 0;
for(int i = 0; i < x.length; i++){
for(int j = 0; j < x[i].length; j++){
if(x[i][j] < 0){
count++;
}
}
}
return (count);
}

Your indexes are reversed from the python version:
while j >= 0 and i < len(array)
To the Java version:
while (i >= 0 && j < x.length)
// Change to
while (j >= 0 && i < x.length)
Output:
max column index is: 2
3
If you are using Java8, you can use streams to implement count_neg:
public static int countNeg(int x[][]) {
long count = Stream.of(x)
.flatMapToInt(arr -> IntStream.of(arr))
.filter(i -> i < 0)
.count();
return Math.toIntExact(count);
}

First of all your algorithm don't find the count of negative numbers.
Here are the results of the python code:
print(count_neg([[1, 1, -1],[1, 1, -1],[1, 1, -1]])) result - 9
print(count_neg([[1, 1, -1],[1, 1, 1],[1, 1, 1]])) result - 3
So the provided code finds sum of column indexes + 1 for some negative numbers, not all. And for your test arrays it's return pseudo correct counts.
To find the count of negative numbers in a two-dimentional array you just have to get each number, check if the one is less than zero and increase the counter by one if it's true. So it's impossible to get the correct result with complexity better than O(n2).
Here the correct code in Java of doing that:
public static int count_neg(int x[][]){
int count = 0;
for(int i = 0; i < x.length; i++){
for(int j = 0; j < x[i].length; j++){
if(x[i][j] < 0) count++;
}
}
return count;
}

Here a small change in the algorithms to produce correct result with columns which don't contain negative numbers:
while j >= 0 and i < len(array):
if array[i][j] < 0:
count += (j + 1)
i += 1
else:
j -= 1
if j < 0:
i += 1
j = len(array) - 1
You can test it with the following array [[1,2,4,5],[-2,-2,1,2],[-1,1,2,3],[1,2,4,5]]

Related

How to get indices as well as array numbers printed out horizontally?

I have an assignment of which a part is to generate n random numbers between 0-99 inclusive in a 1d array, where the user enters n. Now, I have to print out those numbers formatted like this:
What is your number? 22 //user entered
1 2 3 4 5 6 7 8 9 10
----random numbers here---------
11 12 13 14 15 16 17 18 19 20
-----random numbers here--------
21 22
---two random numbers here---
Using those numbers, I have find lots of other things, (like min, max, median, outliers, etc.) and I was able to do so. However, I wasn't able to actually print it out in the format shown above, with no more than 10 numbers in one row.
Edit: Hello, I managed to figure it out, here's how I did it:
int counter = 0;
int count2 = 0;
int count3 = 0;
int add = 0;
int idx = 1;
int idx2 = 0;
if (nums > 10)
{
count3 = 10;
count2 = 10;
}
else
{
count3 = nums;
count2 = nums;
}
if (nums%10 == 0) add = 0;
else add = 1;
for (int i = 0; i < nums/10 + add; i++)
{
for (int j = 0; j < count3; j++)
{
System.out.print(idx + "\t");
idx++;
}
System.out.println();
for (int k = 0; k < count2; k++)
{
System.out.print(numbers[idx2] + "\t");
idx2++;
counter++;
}
System.out.println("\n");
if (nums-counter > 10)
{
count3 = 10;
count2 = 10;
}
else
{
count3 = nums-counter;
count2 = nums-counter;
}
}
Thank you to everyone who helped! Also, please let me know if you find a way to shorten what I have done above.
*above, nums was the number of numbers the user entered
I'd use a for-loop to make an array of arrays: and then formatting the lines using those values:
var arr_random_n = [1,2,3,4,5,6,7,8,9,0,1,2,3,6,4,6,7,4,7,3,1,5,7,9,5,3,2,54,6,8,5,2];
var organized_arr = [];
var idx = 0
for(var i = 0; i < arr.length; i+=10){
organized_arr[idx] = arr.slice(i, i+10); //getting values in groups of 10
idx+=1 //this variable represents the idx of the larger array
}
Now organized_arr has an array of arrays, where each array in index i contains the values to be printed in line i.
There's probably more concise ways of doing this. but this is very intuitive.
Let me know of any improvements.
Something like this might be what you're looking for.
private static void printLine(String msg)
{
System.out.println("\r\n== " + msg + " ==\r\n");
}
private static void printLine(int numDisplayed)
{
printLine(numDisplayed + " above");
}
public static void test(int total)
{
int[] arr = new int[total];
// Fill our array with random values
for (int i = 0; i < total; i++)
arr[i] = (int)(Math.random() * 100);
for (int i = 0; i < total; i++)
{
System.out.print(arr[i] + " ");
// Check if 10th value on the line, if so, display line break
// ** UNLESS it's also the last value - in that case, don't bother, special handling for that
if (i % 10 == 9 && i != total - 1)
printLine("Random Numbers");
}
// Display number of displayed elements above the last line
if (total < 10 || total % 10 != 0)
printLine(total % 10);
else
printLine(10);
}
To print 10 indexes on a line then those elements of an array, use two String variables to build the lines, then print them in two nested loops:
for (int i = 0; i < array.length; i += 10) {
String indexes = "", elements = "";
for (int j = 0; j < 10 && i * 10 + j < array.length; j++) {
int index = i * 10 + j;
indexes += (index + 1) + " "; // one-based as per example in question
elements += array[index] + " ";
}
System.out.println(indexes);
System.out.println(elements);
}

Why does the inner loop range make a difference in the way this problem is solved?

Write a static method printNumbers that takes an integer max as an argument and prints out all perfect numbers that are less than or equal to max.
At first, I kept getting the wrong answer because the inner loop was set to j < max before I changed it to j < i. However, I don't understand why that range would matter, because wouldn't i % j != 0 anyway, even if the range of j were to be larger?
for (int i = 1; i <= max; i++) {
int sum = 0;
for (int j = 1; j < i; j++) {
if (i % j == 0) {
sum += j;
}
}
if (sum == i) {
System.out.print(sum + " ");
}
}
If I changed the inner loop j < max, then printNumbers(6) gives both 1 and 6, but printNumbers(500) gives only 1 and no other number.
If you set j < max in the inner loop, then when j = i, i % j == 0 returns true and skews your result.
This is a good example of a mathematical error to watch out for in coding.

Magic Square gives ArrayIndexOutOfBoundException

I have been working on Magic Square formation, after reading through the algo, I found out there are certain set of rules to be followed while forming the MagicSquare.
The algo which I'm following is :
The magic constant will always be equal to n(n^2 + 1)/2, where n is the dimension given.
Numbers which magicSquare consists will always be equals 1 to n*n.
For the first element that is 1, will always be in the position (n/2, n-1).
Other elements will be placed like (i--,j++)
The condition to be put through for placing an elements are :
a) If i < 0, then i = n-1.
b) If j == n, then j = 0.
c) This is a special case, if i < 0 and j=n happens at the same time, then i = 0, j = n-2.
d) If the position is already occupied by some other element, then i++, j = j-2.
Then input the element inside the magicSquare based upon the conditions.
Based upon the above algo, I have written down a code, and due to some reason I'm getting
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Main.generateMagicSquare(Main.java:25)
at Main.main(Main.java:58)
This is weird. I have checked, and feels like it is safe to use the code to get the desired result, but I don't know where I'm going wrong.
Code
static void generateMagicSquare(int n){
int[][] magicSquare = new int[n][n];
//initialising for pos of the elem 1
int i = n/2, j = n-1;
magicSquare[i][j] = 1;
//the element consist by the magic square will always be equal to 1 to n*n
for(int num=2; num <= n*n; num++){
//it must go like this, for any other element
i--; j++;
// if the element is already present
if(magicSquare[i][j] != 0){
i++;
j -= 2;
}else{
if(i < 0)
i = n-1;
if(j == n)
j = 0;
if(i < 0 && j == n){
i = 0;
j = n-2;
}
}
magicSquare[i][j] = num;
}
for(int k=0; k<n; k++){
for(int l=0; l<n; l++){
System.out.print(magicSquare[k][l] + " ");
}
System.out.println();
}
}
Any help would be appreciated. Thanks. Since I could have copied and pasted the code from internet, but I want to learn it in my way, and your help would help me achieve what I want. :)
EDITS
After reading through the exception, I made some amendments in my code, but still some of the result didn't come upto the mark.
Here is my updated code =======>
static void generateMagicSquare(int n){
int[][] magicSquare = new int[n][n];
//initialising for pos of the elem 1
int i = n/2, j = n-1;
magicSquare[i][j] = 1;
//the element consist by the magic square will always be equal to 1 to n*n
for(int num=2; num <= n*n; num++){
//it must go like this, for any other element
i--; j++;
if(i < 0){
i = n-1;
}
if(j == n){
j = 0;
}
if(i < 0 && j == n){
i = 0;
j = n-2;
}
if(magicSquare[i][j] != 0){
i++;
j -= 2;
}else{
magicSquare[i][j] = num;
}
}
for(int k=0; k<n; k++){
for(int l=0; l<n; l++){
System.out.print(magicSquare[k][l] + " ");
}
System.out.println();
}
}
I get this output :
2 0 6
9 5 1
7 3 0
Still not the right answer to follow.
This line throws the error:
if(magicSquare[i][j] != 0)
and the problem is that the array magicSquare is initialized as:
int[][] magicSquare = new int[n][n];
meaning that it has n columns with indexes from 0 to n - 1 (indexes are zero based).
The variable j is initialized as
j = n-1;
and later this line:
j++;
makes j equal to n
so when you access magicSquare[i][j] you are trying to access magicSquare[i][n] which does not exist.
The index of an array is an integer value that has value in interval [0, n-1], where n is the size of the array. If a request for a negative or an index greater than or equal to size of array is made, then the JAVA throws a ArrayIndexOutOfBounds Exception. You have to check the value of i and j before using it in array. You can use the below code :
for(int num=2; num <= n*n; num++){
i--; j++;
//Here We have to check the value of i and j i.e. it should less than or equal to the length of array.
if((i <= magicSquare[0].length-1 && j <= magicSquare[0].length-1))
{
if(magicSquare[i][j] != 0){
i++;
j -= 2;
}else{
if(i < 0)
i = n-1;
if(j == n)
j = 0;
if(i < 0 && j == n){
i = 0;
j = n-2;
}
}
magicSquare[i][j] = num;
}
}
For understanding ArrayIndexOutOfBoundsException, Please visit :
https://www.geeksforgeeks.org/understanding-array-indexoutofbounds-exception-in-java/

Smallest element array higher than average

i have a two dimensional array, i count average of elements. I'm looking for smallest number in array, higher than counted average
int tmp, tmp1 = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (averageElements < array[i][j]) {
tmp = array[i][j];
if (tmp > tmp1) {
tmp1 = tmp;
}
}
}
}
System.out.println("Smallest element array higher than average " + tmp1);
for example:
1 1 2 1
1 1 1 5
1 1 1 9
1 1 3 1
average elements 2.16
higher than average: 3, 5, 9
smallest number in numbers higher than average -> 3
if (averageElements > array[i][j]) means that you're only looking at values less than the average, exactly opposite of what you want.
tmp1 = 0 and if (array[i][j] > tmp1) means that you are looking for the largest value above zero, also exactly opposite of what you want. And it wouldn't work if all values were negative.
Instead, try this:
int minValue = Integer.MAX_VALUE;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
int value = array[i][j];
if (averageElements < value && value < minValue) {
minValue = value;
}
}
}
System.out.println("Smallest element array higher than average " + minValue);

Backwards Method?

I'm creating a program to create an Identity Matrix - which is pretty easy. But now I need to create the Identity Matrix, but backwards. The result needs to be like so:
0 0 1
0 1 0
1 0 0
Here is the program I'm using that is creating the Identity Matrix:
import java.util.*;
class Lab19Part2 {
public static int[][] create(int size) {
int[][] matrix = new int[size][size];
for(int i = 0; i < size; i++)
for(int j = 0; j < size; j++)
matrix[i][j] = (i == j) ? 1 : 0;
return matrix;
} public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("Enter size of matrix: ");
int size=input.nextInt();
int matrix[][]=create(size);
for (int i=0 ; i < matrix.length ; i++) {
System.out.println();
for (int j=0 ; j < matrix[i].length ; j++){
System.out.print(matrix[i][j]+" ");
}
}
}
}
Though it prints out the Identity Matrix like so:
1 0 0
0 1 0
0 0 1
Question is, how do I make it so it prints out like the first Identity Matrix? I know it has something to do with the for loops but I can't pinpoint it.
Thanks!
You would need to change your condition that controls whether the value is 1 or 0:
matrix[i][j] = (i + j == size - 1) ? 1 : 0;
So that if size is 3, positions [0][2], [1][1], and [2][0] get 1's.
Change
matrix[i][j] = (i == j) ? 1 : 0;
to
matrix[i][j] = (i == size - j - 1) ? 1 : 0;
Why not do this for your identity case:
for(int i = 0; i < size; i++) {
matrix[i][i] = 1;
}
Then for the other case use:
for(int i = 0; i < size; i++) {
matrix[i][size - (i+1)] = 1;
}
Here is the brief example how to create it with la4j (Linear Algebra for Java):
Matrix a = new Basic2DMatrix(Matrices.asIdentitySource(3)).transpose();
// will create a 3x3 matrix
//
// 0 0 1
// 0 1 0
// 1 0 0

Categories

Resources