1

I want to know if there is a faster way than mine, to count how many zeros are inside a 2d array. Here is how I am doing it now.

static int zeroInside = 0;
static int[][] board = new int[][]{
          {5,0,0,0,1,0,0,7,0},
          {1,0,0,0,8,0,3,0,0},
          {0,6,0,2,3,0,0,5,0},
          {2,5,0,7,0,0,6,3,0},
          {9,0,0,3,0,1,0,0,5},
          {0,3,1,0,0,8,0,2,7},
          {0,2,0,0,9,5,0,1,0},
          {0,0,9,0,6,0,0,0,2},
          {0,8,0,0,7,0,0,0,6}}; 
static void initialZeroCounting(){
     for (int outer = 0; outer < board.length;outer++){
         for(int inner = 0; inner < board[outer].length; inner++){
             if (board[outer][inner] ==0){
                 zeroInside++;
             }
         }
     }

I tried many variation of this snippet but without results.

     List<int[]> list = Arrays.asList(board);
     int count = Collections.frequency(list, 0);
4
  • 3
    Your solution is O(n^2). You can't possibly do better in computational complexity level because you have to inspect n^2 elements. Best you can do is perhaps reduce the coefficient, but you're not going to notice a real performance change by doing so unless the array is relatively small, and even then the change will be minimal. Commented Nov 6, 2013 at 13:55
  • 1
    Rather than making your zeroInside static and your function void, make your function return an int, and use a local variable to do the counting. Commented Nov 6, 2013 at 13:56
  • If you stick with your current approach, you may see a performance improvement by assigning board.length and board[outer].length to variables. At present, the length will be evaluated for each iteration of the loop, unless the compiler optimises it out. Commented Nov 6, 2013 at 14:15
  • @Antoniossss I get 0 with the .frequency method for the reasons stated by Marko Topolnik Commented Nov 7, 2013 at 6:13

4 Answers 4

7

Your approach with

List<int[]> list = Arrays.asList(board);
int count = Collections.frequency(list, 0);

fails because you are searching for 0 in a list of int[]. Naturally, the frequency will always be zero. This would seem as a possible avenue:

for (int[] row : board) count += frequency(asList(row), 0);

but unfortunately it fails because Arrays.asList with a primitive-typed argument results in just a single-element List<int[]>. This could be fixed by introducing your own asList to autobox the ints, but that would not be worth it since then performance would suffer quite a bit.

You could also exchange your int[][] for an Integer[][] (the initializer stays the same). This would result in less performance penalty, but now the memory consumption for the array would increase by a factor of 6—again not worth it in my book.

Conclusion: just live with the nested for-loop.

Sign up to request clarification or add additional context in comments.

2 Comments

No, it didn't work for me!! i have tried it first time but it seems no frequency is counted!
True, asList with a primitive-typed array will not work: it will result in a single-member List<int[]>.
5

Since you have to inspect all elements to tell whether it is 0 or not there is no other way then iterating through all of them.

Comments

1

IMO you did it in the best way because you cant avoid to iterate through all items of your array

Comments

0

You could convert your array to a comma separated String using Arrays.deepToString() and then use commons StringUtils.countMatches to count the occurrences of the letter 'zero'.

I'm not suggesting this is any way more performant that iterating the array, just fewer lines of code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.