2

The following code compiles and does what I require. It iterates through an int-based multidimensional array (called nums), and searches for all occurances of the value 1. This program's output is shown below. There are three things to note:

  • Regarding the "outer for" loop statement, I have used Java's comma operator to declare two additional variables.
  • Also regarding this "outer for", I've used another comma operator in the "iteration section", to reset one of these additional variables.
  • Regarding the "inner for", I've used another comma operator in the "iteration section" to increment this additional variable.
int[][] nums = {{1,1,2},{3,4},{5},{6,7,8},{9,1,1}};

for (int i=0, elsSearched=0, foundCount=0; i < nums.length; i++, elsSearched=0) {
    for (int j=0; j < nums[i].length; j++, elsSearched++) {
        if (nums[i][j] == 1) {
            foundCount++;
        }
    }
    System.out.println("Searched " + elsSearched + 
" elements, and found \'number one\' a total of " + foundCount + " times..");
}       

Program output:

Array search results

Could this code be written more effeciently/elegantly?

My other query is about Java's "for each" loop. I tried rewritting the code above using the "for each" loop with the comma operator, but the code wouldn't compile. I quickly came to the obvious conclusion, but would the "for each" loop be better if the comma operator could be used with it, or would that just introduce "distracting clutter"?

jmiserez
  • 2,991
  • 1
  • 23
  • 34
user2911290
  • 1,396
  • 1
  • 16
  • 26
  • I don't think you can do it more efficiently, as you have to look at each element at least once to tell if it is a one ;) – Blub Dec 08 '13 at 11:57
  • Also see [this answer](http://stackoverflow.com/a/256861/202504) regarding the efficiency of for-each loops vs for loops. – jmiserez Dec 08 '13 at 12:06

3 Answers3

2

Edit: Be aware that foundCount is the total number of elements found up until now, as it is never reset to zero. Was this intended?

Don't you agree that this code is easier to read and more concise? (Note: efficiency is the same as your code)

int[][] nums = {{1,1,2},{3,4},{5},{6,7,8},{9,1,1}};

int foundCount = 0; 
for(int[] inner : nums){
    for(int i : inner){
        if (i == 1){
            foundCount++;
        }
    }
    System.out.println("Searched " + inner.length + 
                " elements, and found \'number one\' a total of " + foundCount + " times..");
}

Output:

Searched 3 elements, and found 'number one' a total of 2 times..
Searched 2 elements, and found 'number one' a total of 2 times..
Searched 1 elements, and found 'number one' a total of 2 times..
Searched 3 elements, and found 'number one' a total of 2 times..
Searched 3 elements, and found 'number one' a total of 4 times..
jmiserez
  • 2,991
  • 1
  • 23
  • 34
  • 1
    Excellent, thanks. Yes, the 'foundCount' functionality was as intended, and yes, I do agree with you that your code is both easier to read, and more concise. Thank you. – user2911290 Dec 08 '13 at 12:06
1

First, you probably shouldn't optimize something until you've proven it's a significant contributor to your program runtime. That being said, why not try this instead...

int foundCount = 0;
int totalCount = 0;
for (final int[] i : nums) { // foreach int[] in nums
  for (final int v : i) {    // foreach value v in the int[] from nums
    switch (v) {             // switch on a constant int...
    case 1:                  // The value we seek.
      ++foundCount;          // Add to the foundCount, and fall through!
    default:
      ++totalCount;
    }
  }
}
System.out.println("Searched a total of " + totalCount + 
            " elements and found '#1' a total of " + foundCount);
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • I'm curious, why the `final` keyword? Is there a performance advantage or is it just a safety net? – jmiserez Dec 08 '13 at 12:08
  • Yes. There are optimizations possible when things are immutable (that the runtime and compiler can optimize) and also with using the `switch` versus the `if`. – Elliott Frisch Dec 08 '13 at 12:11
  • Not sure about a jump table for just 3 targets, but I agree on the final. Too bad elegance and efficiency are not always the same. – jmiserez Dec 08 '13 at 12:23
0

If you have performance issues you can try to use binary search (if your array is always sorted) on the sub arrays.

int valueToSearch = 1;

for(int[] inner : nums){

     int foundIndex = Arrays.binarySearch(inner, valueToSearch);

      if (foundIndex >= 0){
          foundCount ++;
       }

}

So you will get a performance of O(n * log(n) ) instead of O(n^2).

I guess you have to do some benchmarks. But the most important thing is to know how your input looks like. Than you can find the best algorithm for it.

sockeqwe
  • 15,574
  • 24
  • 88
  • 144