I am trying to find the indices of all local minima and maxima inside an array.
Example:
int[] array = {5,4,3,3,3,3,3,2,2,2, 6,6,8,5,5,5,3,3,2,1, 1,4,4,7};
I came up with an algorithm about which I have a few questions left:
- Is there much better? :)
- I used Enum with methods to achieve this dualism that UP and STRAIGHT_UP are "UP". Seems dirty to me. Any suggestions?
- Do you have better method names? direction () (+ return value) implies that STRAIGHT is not a directory. But at the same time it is, since it is an element in Emum. Hm.
- It works for a given array. Do you see a situation where this is not so?
-
import java.util.ArrayList; public class MinMaxFinder { private int[] array; private ArrayList<Integer> minima; private ArrayList<Integer> maxima; private enum Direction{ UP, DOWN, STRAIGHT_UP, STRAIGHT_DOWN, STRAIGHT; public Direction direction(){ if(this==UP || this==STRAIGHT_UP){ return UP; }else if(this==DOWN || this==STRAIGHT_DOWN){ return DOWN; }else{ return STRAIGHT; } } public boolean isStraight(){ if(this==STRAIGHT_DOWN || this==STRAIGHT_UP || this==STRAIGHT){ return true; }else{ return false; } } public boolean hasDifferentDirection(Direction other){ if(this!=STRAIGHT && other!=STRAIGHT && this.direction() != other.direction() ){ return true; } return false; } } public MinMaxFinder(int[] array){ this.array = array; } public void update() { minima = new ArrayList<Integer>(); maxima = new ArrayList<Integer>(); Direction segmentDir = Direction.DOWN; int indexOfDirectionChange = 0; int prevVal = array[0]; int arrayLength = array.length; for(int i=1; i<arrayLength; i++){ int currVal = array[i]; Direction currentDir = currVal<prevVal?Direction.DOWN:(currVal>prevVal?Direction.UP:Direction.STRAIGHT); prevVal = currVal; if(currentDir.hasDifferentDirection(segmentDir)){ int changePos = (indexOfDirectionChange+i-1)/2; if(currentDir.direction() == Direction.DOWN){ maxima.add(changePos); }else{ minima.add(changePos); } segmentDir = currentDir; indexOfDirectionChange = i; }else if( currentDir.isStraight() ^ segmentDir.isStraight() ){ indexOfDirectionChange = i; if(currentDir.isStraight() && segmentDir.direction()==Direction.UP){ segmentDir=Direction.STRAIGHT_UP; }else if(currentDir.isStraight() && segmentDir.direction()==Direction.DOWN){ segmentDir=Direction.STRAIGHT_DOWN; }else{ segmentDir = currentDir; } } } } public ArrayList<Integer> getMinima() { return minima; } public ArrayList<Integer> getMaxima() { return maxima; } }
source share