Will you check my Method and let me know what I'm doing wrong? thank you :)
public static void sortByVehicleMakeModel(Vehicle[] vehicles) {
boolean swapped = true;
for(int y = 0; y < vehicles.length && swapped; y++) {
swapped=false;
for(int x = 0; x < vehicles.length - (y+1); x++) {
if(vehicles[x].getMake() && vehicles[x].getModel().compareTo(vehicles[x + 1].getMake() && vehicles[x].getModel())) {
swap(vehicles, x, x + 1);
swapped=true;
}
}
}
}
my error is on the second statement .compareto()
The operator && is undefined for the argument type(s) java.lang.String, java.lang.String
However, this code works just fine:
public static void sortByOwnerName(Vehicle[] vehicles) {
boolean swapped = true;
for(int y = 0; y < vehicles.length && swapped; y++) {
swapped=false;
for(int x = 0; x < vehicles.length - (y + 1); x++) {
if(vehicles[x].getOwner().getName().compareTo(vehicles[x + 1].getOwner().getName())> 0) {
swap(vehicles, x, x + 1);
swapped=true;
}
}
}
}
I would suggest adding a int getCost() to the Vehicle object and then using something like vehicles[x].getCost() > vehicles[x - 1].getCost() for your if statement.
Also, this sort is not very efficient. Maybe Vehicle should implement Comparable and use Collections.sort() to sort.
Just read the update to your question.
Try this:
if (vehicles[x].getMake().compareTo(vehicles[x - 1].getMake()) < 0 ||
(vehicles[x].getMake().compareTo(vehicles[x - 1].getMake()) == 0 &&
vehicles[x].getModel().compareTo(vehicles[x - 1].getModel()) < 0)) {
Both of the operands to the && must be a boolean expression (either true or false):
In the follow either one of them or both of them are String.
vehicles[x].getMake() && vehicles[x].getModel().compareTo(vehicles[x + 1].getMake() && vehicles[x].getModel())
Rather than trying to sort the Vehicle objects with that logic, you should make a comparator for your Vehicle
public class VehicleComparator implements Comparator<Vehicle> {
//...
public int compare(Vehicle v1, Vehicle v2) {
//..
}
}
And use use the Arrays.sort() method.
Arrays.sort(vehicles, new VehicleComparator());
For implementing the compareTo() method you must have to implement Comparable<Type> interface and override
public int compareTo(T o);
method which will return so instead of
vehicles[x].getModel().compareTo(vehicles[x + 1....
you should place
vehicles[x].getModel().compareTo(vehicles[x + 1.... > -1 // or any constant which you want to say as invalid.
Then only work
Hope this will help you.
Related
I have a coordinate system such as this:
public enum Direction {
N ( 0, 1),
NE ( 1, 1),
E ( 1, 0),
SE ( 1, -1),
S ( 0, -1),
SW (-1, -1),
W (-1, 0),
NW (-1, 1);
private int x = 0, y = 0;
private Direction(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Direction combine(Direction direction) {
//unsure
}
}
I'm trying to combine directions with a method within the enum, like:
Direction.N.combine(Direction.E) -> should become Direction.NE
Direction.N.combine(Direction.N) -> null or Direction.N again
My thoughts are to loop through all the values in the enum, and find one that matches its x and y combined:
public Direction combine(Direction direction) {
Direction[] directions = Direction.values();
for (int i = 0; i < directions.length; i++)
if (x + direction.x == directions[i].x && y + direction.y == directions[i].y)
return directions[i];
return this;
}
But I feel like that's an inefficient way to approach this. Is there another way to combine these directions that doesn't involve looping through all the enums?
I also want to create an uncombine function that will reverse the combine.
Direction.NE.uncombine() -> Direction[] {Direction.N, Direction.E}
I could also use the same looping technique, like:
public Direction[] uncombine() {
Direction[] directions = Direction.values(),
rtn = new Direction[2];
for (int i = 0; i < directions.length; i++)
if (x == directions[i].x && directions[i].y == 0)
rtn[0] = directions[i];
for (int i = 0; i < directions.length; i++)
if (y == directions[i].y && directions[i].x == 0)
rtn[1] = directions[i];
return rtn;
}
So is there a more efficient way that I could try out?
I think that creating a Map<Direction, Direction> for each enum value is going to give you a good balance between performance and code neatness.
The combine method becomes:
public Direction combine(Direction other) {
return this.combinerMap.get(other);
}
Of course, you need to build the maps during initialization of the enum class.
Returning null from this method is a bad idea because it pushes the responsibility for sanity checking back onto the caller. So I'd write it like this:
public Direction combine(Direction other)
throws InsaneDirectionsException{
Direction res = this.combineMap.get(other);
if (res == null) {
throw new InsaneDirectionsException(
"Can't combine directions " + this +
" and " + other);
}
return res;
}
If your real class is as simply as the one from the question I think that the most efficient way would be to either manually "hardcode" or pre-calculate (e.g. in static init block) the relationship between argument and result and keep it in map and then only refer to already existing results.
You can keep Map<Byte, Map<Byte, Direction>> where x and y will be indexes. Once you compute new x and y, obtaining Direction will be as simple as matrix.get(x).get(y).
For my programming course I have to write recursive functions, but aside from the theoretical questions given during the classes I can't figure out how to do it with my own code.
If anyone could help me out and give me a pointer on where to start it'd be great!
The method is as follows:
public boolean hasColumn(Marble m) {
boolean hasColumn = false;
for (int i = 0; i < DIM && hasColumn == false; i++) {
int winCount = 0;
for (int j = 0; j < DIM && hasColumn == false; j++) {
if (j == 0) {
winCount = 1;
} else {
if (getField(j, i).equals(getField(j - 1, i))
&& getField(j, i).equals(m)) {
winCount++;
if (winCount == WINLENGTH) {
hasColumn = true;
}
} else {
winCount = 1;
}
}
if (!(getField(j, i).equals(m))) {
hasColumn = false;
}
}
}
return hasColumn;
}
There's a field[DIM][DIM], which stores Marbles. Marble has a Mark, which is 0-4, with 0 being empty and 1-4 being colour values. The method determines whether someone has a marble column of 5 and wins.
Input is the Marble type of a player. Output is boolean hasColumn true or false. The output value is correct, there's just no recursion.
The idea is to make it find a vertical column in a recursive way. This also has to be done with horizontal/vertical, but I figured when I get this figured out I'll manage those by myself.
Thank you in advance!
public boolean hasColumn(Marble m, int i, int j, int wincount) {
if (wincount == WINLENGTH)
return true;
if (i == DIM)
return false;
if (j == DIM)
return hasColumn(m, i + 1, 0, 0);
return hasColumn(m, i, j + 1, getField(j, i).equals(m) ? wincount + 1 : 0);
}
Depending on whether you'd like to find a line/column of elements equal to a given Marble element or rather of same value, you may call this method:
hasColumn(aMarble, 0, 0, 0);
hasColumn(getField(0, 0), 0, 0, 0);
There's a duality between certain types of recursion and iteration.
Consider that in your iterative function you are iteratinng over columns using two variables, i and j. Could you transform those local variables into parameters to the function? You would be transforming state internal to the function (local variables) into state implicit in the function call.
Looks like task sounds like:
1. We have a square matrix of Marble elements(it can be simple integers) with dimension DIM.
2. We have a method getField(int, int) return a marble from this matrix
3. We have an iterative decision to discover if this matrix has any column with equal values of marble elements
Our goal is write recursive variant of this method
So, look here. Recursive algorithm check ROW existing with same value:
public class Marble {
public static final int DIM = 10;
public int[][] marbleAr = new int[DIM][DIM];
public void init(){
for(int i=0;i<DIM;i++){
for(int j=0;j<DIM;j++){
marbleAr[i][j] = new Random().nextInt(10);
if(i == 2){
marbleAr[i][j] = 7;
}
}
}
}
public int get(int i, int j){
return marbleAr[i][j];
}
public void printMarbleAr(){
for(int i=0;i<DIM;i++){
for(int j=0;j<DIM;j++){
System.out.print(marbleAr[i][j] + " ");
}
System.out.println();
}
}
public boolean hasColumn(int val, int col, int row){
if(row == 0){
return true;
}
if(this.hasColumn(val, col, row-1)){
if(this.get(col, row) == this.get(col,row-1)){
return true;
}else{
if(col == DIM-1){
return false;
}
return this.hasColumn(val, col+1, row);
}
}
return false;
}
public static void main(String[] args) {
int v = 7;
Marble marble = new Marble();
marble.init();
marble.printMarbleAr();
System.out.println(marble.hasColumn(v, 0, DIM-1));
}
}
Your method name is hasColumn and return variable
name is hasColumn. That's BAD.
I don't see hasColumn invoked inside the method again to actually
go down to recursion path.
i am currently working on this for personal gratification and would like some advice on how i can make this code faster :
I have one ArrayList composed of an object note, which have coordinates and color value stored in it.
Each "note" is created in real time during the rendering call.
I have made this function :
void keyPressed() {
if (key == 's' || key == 'S') {
PImage img = createImage(posX, specSize, RGB);
for(int x = 0; x < posX; x++){
for(int y = 0; y < specSize; y++){
for(int i = 0; i < notes.size(); i++){
if( (notes.get(i).getX() == x)
&& (notes.get(i).getY() == y) ){
int loc = x + y*posX;
img.pixels[loc] = color(notes.get(i).getR(),
notes.get(i).getG(), notes.get(i).getB());
}
}
}
}
img.updatePixels();
img.save("outputImage.png");
}
}
So when i press the "S" key, i run a loop on the width and height because they can be different in each run, and then on my arrayList and get the corresponding "note" with it's x and y position.
then i write my picture file.
As you can imagine, this is really, really, slow...
Around 5 to 6 minutes for a 1976x256px file.
For me it's okay but it would be great to shorten this a little.
Is there a way to optimize this three loops?
If you need more code, please let me know it's a small code and i don't mind.
How about this?
void keyPressed() {
if (key == 's' || key == 'S') {
PImage img = createImage(posX, specSize, RGB);
for(int i = 0; i < notes.size(); i++){
int x = notes.get(i).getX();
int y = notes.get(i).getY();
int loc = x + y*posX;
img.pixels[loc] = color(notes.get(i).getR(),
notes.get(i).getG(), notes.get(i).getB());
}
img.updatePixels();
img.save("outputImage.png");
}
}
Update:
Not sure what the type of notes is, but something like this might work too. Insert the correct type for one element of Notes into the for loop where I wrote ???.
void keyPressed() {
if (key == 's' || key == 'S') {
PImage img = createImage(posX, specSize, RGB);
for(??? note : notes ){
int x = note.getX();
int y = note.getY();
int loc = x + y * posX;
img.pixels[loc] = color(note.getR(), note.getG(), note.getB());
}
img.updatePixels();
img.save("outputImage.png");
}
}
Can clone notes (and any other object that is used to save) and do this in a different thread so its async to UI. the code will take same or more time but the user can use the rest of the app. Clone is neccesary as you want a snap shot of state when save was clicked.
Dont make a thread put use a ThreadPoolExecutor with one thread max. In the run method could apply what David suggested - one loop instead of two.
Convert your list of notes into a structure mapped like
Map<Integer, Map<Integer, Note> noteMap
Then replace your inner-most loop with a single call like
yNoteMap = note.get(x);
if (yNoteMap != null) {
note = yNoteMap.get(y);
if (note != null) {
// do stuff with note
}
}
Your computational complexity will go from about O(n^3) to O(n^2).
Create a class such as Point with two properties of x and y and implement proper equals and hashcode methods as:
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Point point = (Point) o;
if (x != point.x)
return false;
if (y != point.y)
return false;
return true;
}
#Override
public int hashCode() {
int result = x;
result = 31 * result + y;
return result;
}
}
now put the Point as key of a map, and find your points using this, so you don't have to iterate over the whole lists.
I have a method with a flag argument. I think that passing a boolean to a method is a bad practice (complicates the signature, violates the "each method does one thing" principle). I think splitting the method into two different methods is better. But if I do that, the two methods would be very similar (code duplication).
I wonder if there are some general techniques for splitting methods with a flag argument into two separate methods.
Here's the code of my method (Java):
int calculateNumOfLiveOrDeadNeighbors(Cell c, int gen, boolean countLiveOnes) {
int x = c.getX();
int y = c.getY();
CellState state;
int aliveCounter = 0;
int deadCounter = 0;
for (int i = x - 1; i <= x + 1; i++) {
for (int j = y - 1; j <= y + 1; j++) {
if (i == x && j == y)
continue;
state = getCell(i, j).getCellState(gen);
if (state == CellState.LIVE || state == CellState.SICK){
aliveCounter++;
}
if(state == CellState.DEAD || state == CellState.DEAD4GOOD){
deadCounter++;
}
}
}
if(countLiveOnes){
return aliveCounter;
}
return deadCounter;
}
If you don't like the boolean on your signature, you could add two different methods without it, refactoring to private the main one:
int calculateNumOfLiveNeighbors(Cell c, int gen) {
return calculateNumOfLiveOrDeadNeighbors(c, gen, true);
}
int calculateNumOfDeadNeighbors(Cell c, int gen) {
return calculateNumOfLiveOrDeadNeighbors(c, gen, false);
}
OR
you could code a Result Class or int array as output parameter for storing both the results; this would let you get rid of the annoying boolean parameter.
I guess it depends on every single case.
In this example you have two choices, in my opinion.
Say you want to split the call calculateNumOfLiveOrDeadNeighbors()
in two:
calculateNumOfLiveNeighbors()
and
calculateNumOfDeadNeighbors()
You can use Template Method to move the loop to another method.
You can use it to count dead / alive cells in the two methods.
private int countCells(Cell c, int gen, Filter filter)
{
int x = c.getX();
int y = c.getY();
CellState state;
int counter = 0;
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if (i == x && j == y)
continue;
state = getCell(i, j).getCellState(gen);
if (filter.countMeIn(state))
{
counter++;
}
}
}
return counter;
}
private interface Filter
{
boolean countMeIn(State state);
}
public int calculateNumOfDeadNeighbors(Cell c, int gen)
{
return countCells(c, gen, new Filter()
{
public boolean countMeIn(CellState state)
{
return (state == CellState.DEAD || state == CellState.DEAD4GOOD);
}
});
}
public int calculateNumOfLiveNeighbors(Cell c, int gen)
{
return countCells(c, gen, new Filter()
{
public boolean countMeIn(CellState state)
{
return (state == CellState.LIVE || state == CellState.SICK);
}
});
}
It's cumbersome, maybe not even worth the pain. You can, alternatively, use a monad to store the results of your statistics calculation and then use getDeadCounter() or getLiveCounter() on the monad, as many suggested already.
you can try to extract the common functionality in a single method and only use the specific functionality
you can create a private method with that flag, and invoke it from the two public methods. Thus your public API will not have the 'complicated' method signature, and you won't have duplicated code
make a method that returns both values, and choose one in each caller (public method).
In the example above I think the 2nd and 3rd options are more applicable.
Seems like the most semantically clean approach would be to return a result object that contains both values, and let the calling code extract what it cares about from the result object.
Like Bozho said: But but combine point 2 and 3 in the other way arround:
Create a (possible private method) that returns both (living and dead) and (only if you need dead or alive seperate in the most cases) then add two methods that pick dead or both out of the result:
DeadLiveCounter calcLiveAndDead(..) {}
int calcLive(..) { return calcLiveAndDead(..).getLive; }
int calcDead(..) { return calcLiveAndDead(..).getDead; }
IMO, this so-called "each method does one thing" principle needs to be applied selectively. Your example is one where, it is probably better NOT to apply it. Rather, I'd just simplify the method implementation a bit:
int countNeighbors(Cell c, int gen, boolean countLive) {
int x = c.getX();
int y = c.getY();
int counter = 0;
for (int i = x - 1; i <= x + 1; i++) {
for (int j = y - 1; j <= y + 1; j++) {
if (i == x && j == y)
continue;
CellState s = getCell(i, j).getCellState(gen);
if ((countLive && (s == CellState.LIVE || s == CellState.SICK)) ||
(!countLive && (s == CellState.DEAD || s == CellState.DEAD4GOOD))) {
counter++;
}
}
}
return counter;
}
In terms of using refactoring, some things you can do are;
copy the method and create two version, one with true hard coded and the other false hard coded. Your refactoring tools should help you inline this constant and remove code as required.
recreate the method which calls the right true/false method as above for backward compatibility. You can then inline this method.
I would be inclined here to keep a map from the CellState enum to count, then add the LIVE and the SICK or the DEAD and the DEAD4GOOD as needed.
int calculateNumOfLiveOrDeadNeighbors(Cell c, int gen, boolean countLiveOnes) {
final int x = c.getX();
final int y = c.getY();
final HashMap<CellState, Integer> counts = new HashMap<CellState, Integer>();
for (CellState state : CellState.values())
counts.put(state, 0);
for (int i = x - 1; i < x + 2; i++) {
for (int j = y - 1; j < y + 2; j++) {
if (i == x && j == y)
continue;
CellState state = getCell(i, j).getCellState(gen);
counts.put(state, counts.get(state) + 1);
}
}
if (countLiveOnes)
return counts.get(CellState.LIVE) + counts.get(CellState.SICK);
else
return counts.get(CellState.DEAD) + counts.get(CellState.DEAD4GOOD);
}
have a private method which is an exact copy and paste of what you currently have.
Then create two new methods, each with a more descriptive name that simply call your private method with appropriate boolean
I am wondering how you would write a simple java method finding the closest Integer to a given value in a sorted Integer list.
Here is my first attempt:
public class Closest {
private static List<Integer> integers = new ArrayList<Integer>();
static {
for (int i = 0; i <= 10; i++) {
integers.add(Integer.valueOf(i * 10));
}
}
public static void main(String[] args) {
Integer closest = null;
Integer arg = Integer.valueOf(args[0]);
int index = Collections.binarySearch(
integers, arg);
if (index < 0) /*arg doesn't exist in integers*/ {
index = -index - 1;
if (index == integers.size()) {
closest = integers.get(index - 1);
} else if (index == 0) {
closest = integers.get(0);
} else {
int previousDate = integers.get(index - 1);
int nextDate = integers.get(index);
if (arg - previousDate < nextDate - arg) {
closest = previousDate;
} else {
closest = nextDate;
}
}
} else /*arg exists in integers*/ {
closest = integers.get(index);
}
System.out.println("The closest Integer to " + arg + " in " + integers
+ " is " + closest);
}
}
What do you think about this solution ? I am sure there is a cleaner way to do this job.
Maybe such method exists somewhere in the Java libraries and I missed it ?
try this little method:
public int closest(int of, List<Integer> in) {
int min = Integer.MAX_VALUE;
int closest = of;
for (int v : in) {
final int diff = Math.abs(v - of);
if (diff < min) {
min = diff;
closest = v;
}
}
return closest;
}
some testcases:
private final static List<Integer> list = Arrays.asList(10, 20, 30, 40, 50);
#Test
public void closestOf21() {
assertThat(closest(21, list), is(20));
}
#Test
public void closestOf19() {
assertThat(closest(19, list), is(20));
}
#Test
public void closestOf20() {
assertThat(closest(20, list), is(20));
}
Kotlin is so helpful
fun List<Int>.closestValue(value: Int) = minBy { abs(value - it) }
val values = listOf(1, 8, 4, -6)
println(values.closestValue(-7)) // -6
println(values.closestValue(2)) // 1
println(values.closestValue(7)) // 8
List doesn't need to be sorted BTW
Edit: since kotlin 1.4, minBy is deprecated. Prefer minByOrNull
#Deprecated("Use minByOrNull instead.", ReplaceWith("this.minByOrNull(selector)"))
#DeprecatedSinceKotlin(warningSince = "1.4")
A solution without binary search (takes advantage of list being sorted):
public int closest(int value, int[] sorted) {
if(value < sorted[0])
return sorted[0];
int i = 1;
for( ; i < sorted.length && value > sorted[i] ; i++);
if(i >= sorted.length)
return sorted[sorted.length - 1];
return Math.abs(value - sorted[i]) < Math.abs(value - sorted[i-1]) ?
sorted[i] : sorted[i-1];
}
To solve the problem, I'd extend the Comparable Interface by a distanceTo method. The implementation of distanceTo returns a double value that represents the intended distance and which is compatible with the result of the compareTo implementation.
The following example illustrates the idea with just apples. You can exchange diameter by weight, volume or sweetness. The bag will always return the 'closest' apple (most similiar in size, wight or taste)
public interface ExtComparable<T> extends Comparable<T> {
public double distanceTo(T other);
}
public class Apple implements Comparable<Apple> {
private Double diameter;
public Apple(double diameter) {
this.diameter = diameter;
}
public double distanceTo(Apple o) {
return diameter - o.diameter;
}
public int compareTo(Apple o) {
return (int) Math.signum(distanceTo(o));
}
}
public class AppleBag {
private List<Apple> bag = new ArrayList<Apple>();
public addApples(Apple...apples){
bag.addAll(Arrays.asList(apples));
Collections.sort(bag);
}
public removeApples(Apple...apples){
bag.removeAll(Arrays.asList(apples));
}
public Apple getClosest(Apple apple) {
Apple closest = null;
boolean appleIsInBag = bag.contains(apple);
if (!appleIsInBag) {
bag.addApples(apple);
}
int appleIndex = bag.indexOf(apple);
if (appleIndex = 0) {
closest = bag.get(1);
} else if(appleIndex = bag.size()-1) {
closest = bag.get(bag.size()-2);
} else {
double absDistToPrev = Math.abs(apple.distanceTo(bag.get(appleIndex-1));
double absDistToNext = Math.abs(apple.distanceTo(bag.get(appleIndex+1));
closest = bag.get(absDistToNext < absDistToPrev ? next : previous);
}
if (!appleIsInBag) {
bag.removeApples(apple);
}
return closest;
}
}
Certainly you can simply use a for loop to go through the and keep track of the difference between the value you are on and the value. It would look cleaner, but be much slower.
See: Finding closest match in collection of numbers
I think what you have is about the simplest and most efficient way to do it. Finding the "closest" item in a sorted list isn't something that is commonly encountered in programming (you typically look for the one that is bigger, or the one that is smaller). The problem only makes sense for numeric types, so is not very generalizable, and thus it would be unusual to have a library function for it.
Not tested
int[] randomArray; // your array you want to find the closest
int theValue; // value the closest should be near to
for (int i = 0; i < randomArray.length; i++) {
int compareValue = randomArray[i];
randomArray[i] -= theValue;
}
int indexOfClosest = 0;
for (int i = 1; i < randomArray.length; i++) {
int compareValue = randomArray[i];
if(Math.abs(randomArray[indexOfClosest] > Math.abs(randomArray[i]){
indexOfClosest = i;
}
}
I think your answer is probably the most efficient way to return a single result.
However, the problem with your approach is that there are 0 (if there is no list), 1, or 2 possible solutions. It's when you have two possible solutions to a function that your problems really start: What if this is not the final answer, but only the first in a series of steps to determine an optimal course of action, and the answer that you didn't return would have provided a better solution? The only correct thing to do would be to consider both answers and compare the results of further processing only at the end.
Think of the square root function as a somewhat analogous problem to this.
If you're not massively concerned on performance (given that the set is searched twice), I think using a Navigable set leads to clearer code:
public class Closest
{
private static NavigableSet<Integer> integers = new TreeSet<Integer>();
static
{
for (int i = 0; i <= 10; i++)
{
integers.add(Integer.valueOf(i * 10));
}
}
public static void main(String[] args)
{
final Integer arg = Integer.valueOf(args[0]);
final Integer lower = integers.lower(arg);
final Integer higher = integers.higher(arg);
final Integer closest;
if (lower != null)
{
if (higher != null)
closest = (higher - arg > arg - lower) ? lower : higher;
else
closest = lower;
}
else
closest = higher;
System.out.println("The closest Integer to " + arg + " in " + integers + " is " + closest);
}
}
Your solution appears to be asymptotically optimal. It might be slightly faster (though probably less maintainable) if it used Math.min/max. A good JIT likely has intrinsics that make these fast.
int index = Collections.binarySearch(integers, arg);
if (index < 0) {
int previousDate = integers.get(Math.max(0, -index - 2));
int nextDate = integers.get(Math.min(integers.size() - 1, -index - 1));
closest = arg - previousDate < nextDate - arg ? previousDate : nextDate;
} else {
closest = integers.get(index);
}
Probably a bit late, but this WILL work, this is a data structure binary search:
Kotlin:
fun binarySearch(list: List<Int>, valueToCompare: Int): Int {
var central: Int
var initialPosition = 0
var lastPosition: Int
var centralValue: Int
lastPosition = list.size - 1
while (initialPosition <= lastPosition) {
central = (initialPosition + lastPosition) / 2 //Central index
centralValue = list[central] //Central index value
when {
valueToCompare == centralValue -> {
return centralValue //found; returns position
}
valueToCompare < centralValue -> {
lastPosition = central - 1 //position changes to the previous index
}
else -> {
initialPosition = central + 1 //position changes to next index
}
}
}
return -1 //element not found
}
Java:
public int binarySearch(int list[], int valueToCompare) {
int central;
int centralValue;
int initialPosition = 0;
int lastPosition = list . length -1;
while (initialPosition <= lastPosition) {
central = (initialPosition + lastPosition) / 2; //central index
centralValue = list[central]; //central index value
if (valueToCompare == centralValue) {
return centralValue; //element found; returns position
} else if (valueToCompare < centralValue) {
lastPosition = central - 1; //Position changes to the previous index
} else {
initialPosition = central + 1; //Position changes to the next index
}
return -1; //element not found
}
}
I hope this helps, happy coding.