Binary search for integers

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
0
down vote
favorite
I've written binary search with only my own efforts ðªðª without glancing at anywhere. I stuck on finding base case. At final, I think that if last checking is less than first index or first checking is greater than last index, it stops. But, I'm still suspicious of its performance and righness. I could return Integer.MAX_VALUE or Integer.MIN_VALUE if the searched number is not in the array but I assumed that all numbers are positive.
In the beginning times of writing recursion, I had difficulty in thinking recursively. But, now I have difficulty in finding base case(s).
public static int binarySearch(int arr, int key, int low, int high)
if (high < 0
java algorithm recursion binary-search
add a comment |Â
up vote
0
down vote
favorite
I've written binary search with only my own efforts ðªðª without glancing at anywhere. I stuck on finding base case. At final, I think that if last checking is less than first index or first checking is greater than last index, it stops. But, I'm still suspicious of its performance and righness. I could return Integer.MAX_VALUE or Integer.MIN_VALUE if the searched number is not in the array but I assumed that all numbers are positive.
In the beginning times of writing recursion, I had difficulty in thinking recursively. But, now I have difficulty in finding base case(s).
public static int binarySearch(int arr, int key, int low, int high)
if (high < 0
java algorithm recursion binary-search
If you added javadocs, you could have added that theint arrhas to be sorted ;)
â RobAu
May 16 at 14:16
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I've written binary search with only my own efforts ðªðª without glancing at anywhere. I stuck on finding base case. At final, I think that if last checking is less than first index or first checking is greater than last index, it stops. But, I'm still suspicious of its performance and righness. I could return Integer.MAX_VALUE or Integer.MIN_VALUE if the searched number is not in the array but I assumed that all numbers are positive.
In the beginning times of writing recursion, I had difficulty in thinking recursively. But, now I have difficulty in finding base case(s).
public static int binarySearch(int arr, int key, int low, int high)
if (high < 0
java algorithm recursion binary-search
I've written binary search with only my own efforts ðªðª without glancing at anywhere. I stuck on finding base case. At final, I think that if last checking is less than first index or first checking is greater than last index, it stops. But, I'm still suspicious of its performance and righness. I could return Integer.MAX_VALUE or Integer.MIN_VALUE if the searched number is not in the array but I assumed that all numbers are positive.
In the beginning times of writing recursion, I had difficulty in thinking recursively. But, now I have difficulty in finding base case(s).
public static int binarySearch(int arr, int key, int low, int high)
if (high < 0
java algorithm recursion binary-search
edited May 15 at 17:20
200_success
123k14143399
123k14143399
asked May 15 at 13:38
itsnotmyrealname
1375
1375
If you added javadocs, you could have added that theint arrhas to be sorted ;)
â RobAu
May 16 at 14:16
add a comment |Â
If you added javadocs, you could have added that theint arrhas to be sorted ;)
â RobAu
May 16 at 14:16
If you added javadocs, you could have added that the
int arr has to be sorted ;)â RobAu
May 16 at 14:16
If you added javadocs, you could have added that the
int arr has to be sorted ;)â RobAu
May 16 at 14:16
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
2
down vote
accepted
I don't immediately see something wrong with your base case. Perhaps it could be simplified, checking only for low > high. You would need to think about what happens if you pass Integer.MAX_VALUE as high then though.
That being said, the implementation contains a major bug. low + high will overflow when the sum of them is greater than Integer.MAX_VALUE. You can use some mathematical tricks to solve this. Or use some bitwise operations, like (low + high) >>> 1.
The bitshift solution works for positive low and high (which they are). Although the sum can indeed still overflow, the unsigned shift operator >>> shifts a zero in the most significant side. Mathematically, you could think of it as dividing the number interpreted as unsigned by two. As an example:
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
--------------------------------------- +
1111 1111 1111 1111 1111 1111 1111 1110 = -2 ((2^32)-2 if interpreted as unsigned)
This sum overflows. Now, the difference between division (which would be the same as signed shift >>) and unsigned shift:
(-2) / 2 = 1111 1111 1111 1111 1111 1111 1111 1111 = -1
(-2) >>> 2 = 0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
Also note that the recursive calls may lead to a stack overflow in Java. Although it is a tail recursive implementation, this is not optimized in Java. So for a real world implementation, prefer iteration.
Final note: always try to use braces with if/else blocks.
could you explain how(low + high) >>> 1works? What if(low + high)overflows?
â itsnotmyrealname
May 16 at 8:31
@itsnotmyrealname I updated the answer, does it clear up why it works?
â Koekje
May 16 at 10:24
Yes, thank you indeed.
â itsnotmyrealname
May 16 at 10:25
add a comment |Â
up vote
0
down vote
Computation of
(high + low)/2may overflow. Preferlow + (high - low)/2.intis a wrong type for an index. An array can be large enough to go beyond the range ofint. The only type which guarantees to hold an index into an array issize_t.As a side note, in the context of binary search it makes no sense to index an array with a signed type. One perk benefit is elimination of
high < 0test.I strongly recommend to not use indices at all, but use pointers to the beginning and the end of the range being searched.
The what to return in case of failure is a common problem. It is enough to say that
stdlibimplementation got it wrong. The very same problem also manifests when the array contains multiple elements matching the key: the routine returns pretty much randomly. Not a problem with integers, but definitely a problem with more complex data.An answer is to always return the exact lower bound, STL style: do not short circuit as soon as you found the key, but keep going until you find its leftmost occurrence. If the key is not there, the lower bound would represent the insertion point, that is were the key would be inserted keeping an array sorted.
The recursive invocation
binarySearch(arr, key, low, middleIndex - 1);suggests that the
low..highrange is inclusive. Most algorithms are expressed better on the semi-open range, that is, withhighis just beyond the range. Notice that if the key is greater than everything in the array, its lower bound(see above) is just beyond the range.
It is also worth mentioning that binary search is not the best problem to exercise recursion. I strongly recommend to recognize that it in fact is a tail recursion, and to rewrite it iteratively.
2
Did you answer this with a different language in mind? :D
â Koekje
May 15 at 18:34
@Koekje what made you think so? Mentioning STL doesn't imply C++. STL shows how the algorithm should be written, regardless of the language.
â vnp
May 15 at 18:41
1
Mentioning pointers, unsigned types (specifically saying it makes no sense to index with a signed type) :)
â Koekje
May 15 at 18:58
2
Java arrays are indexed withint, and there is nosize_tin Java ...
â Martin R
May 15 at 20:43
@MartinR Shame on me. I misread the tag.
â vnp
May 15 at 21:00
 |Â
show 1 more comment
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
I don't immediately see something wrong with your base case. Perhaps it could be simplified, checking only for low > high. You would need to think about what happens if you pass Integer.MAX_VALUE as high then though.
That being said, the implementation contains a major bug. low + high will overflow when the sum of them is greater than Integer.MAX_VALUE. You can use some mathematical tricks to solve this. Or use some bitwise operations, like (low + high) >>> 1.
The bitshift solution works for positive low and high (which they are). Although the sum can indeed still overflow, the unsigned shift operator >>> shifts a zero in the most significant side. Mathematically, you could think of it as dividing the number interpreted as unsigned by two. As an example:
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
--------------------------------------- +
1111 1111 1111 1111 1111 1111 1111 1110 = -2 ((2^32)-2 if interpreted as unsigned)
This sum overflows. Now, the difference between division (which would be the same as signed shift >>) and unsigned shift:
(-2) / 2 = 1111 1111 1111 1111 1111 1111 1111 1111 = -1
(-2) >>> 2 = 0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
Also note that the recursive calls may lead to a stack overflow in Java. Although it is a tail recursive implementation, this is not optimized in Java. So for a real world implementation, prefer iteration.
Final note: always try to use braces with if/else blocks.
could you explain how(low + high) >>> 1works? What if(low + high)overflows?
â itsnotmyrealname
May 16 at 8:31
@itsnotmyrealname I updated the answer, does it clear up why it works?
â Koekje
May 16 at 10:24
Yes, thank you indeed.
â itsnotmyrealname
May 16 at 10:25
add a comment |Â
up vote
2
down vote
accepted
I don't immediately see something wrong with your base case. Perhaps it could be simplified, checking only for low > high. You would need to think about what happens if you pass Integer.MAX_VALUE as high then though.
That being said, the implementation contains a major bug. low + high will overflow when the sum of them is greater than Integer.MAX_VALUE. You can use some mathematical tricks to solve this. Or use some bitwise operations, like (low + high) >>> 1.
The bitshift solution works for positive low and high (which they are). Although the sum can indeed still overflow, the unsigned shift operator >>> shifts a zero in the most significant side. Mathematically, you could think of it as dividing the number interpreted as unsigned by two. As an example:
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
--------------------------------------- +
1111 1111 1111 1111 1111 1111 1111 1110 = -2 ((2^32)-2 if interpreted as unsigned)
This sum overflows. Now, the difference between division (which would be the same as signed shift >>) and unsigned shift:
(-2) / 2 = 1111 1111 1111 1111 1111 1111 1111 1111 = -1
(-2) >>> 2 = 0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
Also note that the recursive calls may lead to a stack overflow in Java. Although it is a tail recursive implementation, this is not optimized in Java. So for a real world implementation, prefer iteration.
Final note: always try to use braces with if/else blocks.
could you explain how(low + high) >>> 1works? What if(low + high)overflows?
â itsnotmyrealname
May 16 at 8:31
@itsnotmyrealname I updated the answer, does it clear up why it works?
â Koekje
May 16 at 10:24
Yes, thank you indeed.
â itsnotmyrealname
May 16 at 10:25
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
I don't immediately see something wrong with your base case. Perhaps it could be simplified, checking only for low > high. You would need to think about what happens if you pass Integer.MAX_VALUE as high then though.
That being said, the implementation contains a major bug. low + high will overflow when the sum of them is greater than Integer.MAX_VALUE. You can use some mathematical tricks to solve this. Or use some bitwise operations, like (low + high) >>> 1.
The bitshift solution works for positive low and high (which they are). Although the sum can indeed still overflow, the unsigned shift operator >>> shifts a zero in the most significant side. Mathematically, you could think of it as dividing the number interpreted as unsigned by two. As an example:
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
--------------------------------------- +
1111 1111 1111 1111 1111 1111 1111 1110 = -2 ((2^32)-2 if interpreted as unsigned)
This sum overflows. Now, the difference between division (which would be the same as signed shift >>) and unsigned shift:
(-2) / 2 = 1111 1111 1111 1111 1111 1111 1111 1111 = -1
(-2) >>> 2 = 0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
Also note that the recursive calls may lead to a stack overflow in Java. Although it is a tail recursive implementation, this is not optimized in Java. So for a real world implementation, prefer iteration.
Final note: always try to use braces with if/else blocks.
I don't immediately see something wrong with your base case. Perhaps it could be simplified, checking only for low > high. You would need to think about what happens if you pass Integer.MAX_VALUE as high then though.
That being said, the implementation contains a major bug. low + high will overflow when the sum of them is greater than Integer.MAX_VALUE. You can use some mathematical tricks to solve this. Or use some bitwise operations, like (low + high) >>> 1.
The bitshift solution works for positive low and high (which they are). Although the sum can indeed still overflow, the unsigned shift operator >>> shifts a zero in the most significant side. Mathematically, you could think of it as dividing the number interpreted as unsigned by two. As an example:
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
--------------------------------------- +
1111 1111 1111 1111 1111 1111 1111 1110 = -2 ((2^32)-2 if interpreted as unsigned)
This sum overflows. Now, the difference between division (which would be the same as signed shift >>) and unsigned shift:
(-2) / 2 = 1111 1111 1111 1111 1111 1111 1111 1111 = -1
(-2) >>> 2 = 0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE
Also note that the recursive calls may lead to a stack overflow in Java. Although it is a tail recursive implementation, this is not optimized in Java. So for a real world implementation, prefer iteration.
Final note: always try to use braces with if/else blocks.
edited May 16 at 10:20
answered May 15 at 18:31
Koekje
1,017211
1,017211
could you explain how(low + high) >>> 1works? What if(low + high)overflows?
â itsnotmyrealname
May 16 at 8:31
@itsnotmyrealname I updated the answer, does it clear up why it works?
â Koekje
May 16 at 10:24
Yes, thank you indeed.
â itsnotmyrealname
May 16 at 10:25
add a comment |Â
could you explain how(low + high) >>> 1works? What if(low + high)overflows?
â itsnotmyrealname
May 16 at 8:31
@itsnotmyrealname I updated the answer, does it clear up why it works?
â Koekje
May 16 at 10:24
Yes, thank you indeed.
â itsnotmyrealname
May 16 at 10:25
could you explain how
(low + high) >>> 1 works? What if (low + high) overflows?â itsnotmyrealname
May 16 at 8:31
could you explain how
(low + high) >>> 1 works? What if (low + high) overflows?â itsnotmyrealname
May 16 at 8:31
@itsnotmyrealname I updated the answer, does it clear up why it works?
â Koekje
May 16 at 10:24
@itsnotmyrealname I updated the answer, does it clear up why it works?
â Koekje
May 16 at 10:24
Yes, thank you indeed.
â itsnotmyrealname
May 16 at 10:25
Yes, thank you indeed.
â itsnotmyrealname
May 16 at 10:25
add a comment |Â
up vote
0
down vote
Computation of
(high + low)/2may overflow. Preferlow + (high - low)/2.intis a wrong type for an index. An array can be large enough to go beyond the range ofint. The only type which guarantees to hold an index into an array issize_t.As a side note, in the context of binary search it makes no sense to index an array with a signed type. One perk benefit is elimination of
high < 0test.I strongly recommend to not use indices at all, but use pointers to the beginning and the end of the range being searched.
The what to return in case of failure is a common problem. It is enough to say that
stdlibimplementation got it wrong. The very same problem also manifests when the array contains multiple elements matching the key: the routine returns pretty much randomly. Not a problem with integers, but definitely a problem with more complex data.An answer is to always return the exact lower bound, STL style: do not short circuit as soon as you found the key, but keep going until you find its leftmost occurrence. If the key is not there, the lower bound would represent the insertion point, that is were the key would be inserted keeping an array sorted.
The recursive invocation
binarySearch(arr, key, low, middleIndex - 1);suggests that the
low..highrange is inclusive. Most algorithms are expressed better on the semi-open range, that is, withhighis just beyond the range. Notice that if the key is greater than everything in the array, its lower bound(see above) is just beyond the range.
It is also worth mentioning that binary search is not the best problem to exercise recursion. I strongly recommend to recognize that it in fact is a tail recursion, and to rewrite it iteratively.
2
Did you answer this with a different language in mind? :D
â Koekje
May 15 at 18:34
@Koekje what made you think so? Mentioning STL doesn't imply C++. STL shows how the algorithm should be written, regardless of the language.
â vnp
May 15 at 18:41
1
Mentioning pointers, unsigned types (specifically saying it makes no sense to index with a signed type) :)
â Koekje
May 15 at 18:58
2
Java arrays are indexed withint, and there is nosize_tin Java ...
â Martin R
May 15 at 20:43
@MartinR Shame on me. I misread the tag.
â vnp
May 15 at 21:00
 |Â
show 1 more comment
up vote
0
down vote
Computation of
(high + low)/2may overflow. Preferlow + (high - low)/2.intis a wrong type for an index. An array can be large enough to go beyond the range ofint. The only type which guarantees to hold an index into an array issize_t.As a side note, in the context of binary search it makes no sense to index an array with a signed type. One perk benefit is elimination of
high < 0test.I strongly recommend to not use indices at all, but use pointers to the beginning and the end of the range being searched.
The what to return in case of failure is a common problem. It is enough to say that
stdlibimplementation got it wrong. The very same problem also manifests when the array contains multiple elements matching the key: the routine returns pretty much randomly. Not a problem with integers, but definitely a problem with more complex data.An answer is to always return the exact lower bound, STL style: do not short circuit as soon as you found the key, but keep going until you find its leftmost occurrence. If the key is not there, the lower bound would represent the insertion point, that is were the key would be inserted keeping an array sorted.
The recursive invocation
binarySearch(arr, key, low, middleIndex - 1);suggests that the
low..highrange is inclusive. Most algorithms are expressed better on the semi-open range, that is, withhighis just beyond the range. Notice that if the key is greater than everything in the array, its lower bound(see above) is just beyond the range.
It is also worth mentioning that binary search is not the best problem to exercise recursion. I strongly recommend to recognize that it in fact is a tail recursion, and to rewrite it iteratively.
2
Did you answer this with a different language in mind? :D
â Koekje
May 15 at 18:34
@Koekje what made you think so? Mentioning STL doesn't imply C++. STL shows how the algorithm should be written, regardless of the language.
â vnp
May 15 at 18:41
1
Mentioning pointers, unsigned types (specifically saying it makes no sense to index with a signed type) :)
â Koekje
May 15 at 18:58
2
Java arrays are indexed withint, and there is nosize_tin Java ...
â Martin R
May 15 at 20:43
@MartinR Shame on me. I misread the tag.
â vnp
May 15 at 21:00
 |Â
show 1 more comment
up vote
0
down vote
up vote
0
down vote
Computation of
(high + low)/2may overflow. Preferlow + (high - low)/2.intis a wrong type for an index. An array can be large enough to go beyond the range ofint. The only type which guarantees to hold an index into an array issize_t.As a side note, in the context of binary search it makes no sense to index an array with a signed type. One perk benefit is elimination of
high < 0test.I strongly recommend to not use indices at all, but use pointers to the beginning and the end of the range being searched.
The what to return in case of failure is a common problem. It is enough to say that
stdlibimplementation got it wrong. The very same problem also manifests when the array contains multiple elements matching the key: the routine returns pretty much randomly. Not a problem with integers, but definitely a problem with more complex data.An answer is to always return the exact lower bound, STL style: do not short circuit as soon as you found the key, but keep going until you find its leftmost occurrence. If the key is not there, the lower bound would represent the insertion point, that is were the key would be inserted keeping an array sorted.
The recursive invocation
binarySearch(arr, key, low, middleIndex - 1);suggests that the
low..highrange is inclusive. Most algorithms are expressed better on the semi-open range, that is, withhighis just beyond the range. Notice that if the key is greater than everything in the array, its lower bound(see above) is just beyond the range.
It is also worth mentioning that binary search is not the best problem to exercise recursion. I strongly recommend to recognize that it in fact is a tail recursion, and to rewrite it iteratively.
Computation of
(high + low)/2may overflow. Preferlow + (high - low)/2.intis a wrong type for an index. An array can be large enough to go beyond the range ofint. The only type which guarantees to hold an index into an array issize_t.As a side note, in the context of binary search it makes no sense to index an array with a signed type. One perk benefit is elimination of
high < 0test.I strongly recommend to not use indices at all, but use pointers to the beginning and the end of the range being searched.
The what to return in case of failure is a common problem. It is enough to say that
stdlibimplementation got it wrong. The very same problem also manifests when the array contains multiple elements matching the key: the routine returns pretty much randomly. Not a problem with integers, but definitely a problem with more complex data.An answer is to always return the exact lower bound, STL style: do not short circuit as soon as you found the key, but keep going until you find its leftmost occurrence. If the key is not there, the lower bound would represent the insertion point, that is were the key would be inserted keeping an array sorted.
The recursive invocation
binarySearch(arr, key, low, middleIndex - 1);suggests that the
low..highrange is inclusive. Most algorithms are expressed better on the semi-open range, that is, withhighis just beyond the range. Notice that if the key is greater than everything in the array, its lower bound(see above) is just beyond the range.
It is also worth mentioning that binary search is not the best problem to exercise recursion. I strongly recommend to recognize that it in fact is a tail recursion, and to rewrite it iteratively.
answered May 15 at 18:29
vnp
36.4k12890
36.4k12890
2
Did you answer this with a different language in mind? :D
â Koekje
May 15 at 18:34
@Koekje what made you think so? Mentioning STL doesn't imply C++. STL shows how the algorithm should be written, regardless of the language.
â vnp
May 15 at 18:41
1
Mentioning pointers, unsigned types (specifically saying it makes no sense to index with a signed type) :)
â Koekje
May 15 at 18:58
2
Java arrays are indexed withint, and there is nosize_tin Java ...
â Martin R
May 15 at 20:43
@MartinR Shame on me. I misread the tag.
â vnp
May 15 at 21:00
 |Â
show 1 more comment
2
Did you answer this with a different language in mind? :D
â Koekje
May 15 at 18:34
@Koekje what made you think so? Mentioning STL doesn't imply C++. STL shows how the algorithm should be written, regardless of the language.
â vnp
May 15 at 18:41
1
Mentioning pointers, unsigned types (specifically saying it makes no sense to index with a signed type) :)
â Koekje
May 15 at 18:58
2
Java arrays are indexed withint, and there is nosize_tin Java ...
â Martin R
May 15 at 20:43
@MartinR Shame on me. I misread the tag.
â vnp
May 15 at 21:00
2
2
Did you answer this with a different language in mind? :D
â Koekje
May 15 at 18:34
Did you answer this with a different language in mind? :D
â Koekje
May 15 at 18:34
@Koekje what made you think so? Mentioning STL doesn't imply C++. STL shows how the algorithm should be written, regardless of the language.
â vnp
May 15 at 18:41
@Koekje what made you think so? Mentioning STL doesn't imply C++. STL shows how the algorithm should be written, regardless of the language.
â vnp
May 15 at 18:41
1
1
Mentioning pointers, unsigned types (specifically saying it makes no sense to index with a signed type) :)
â Koekje
May 15 at 18:58
Mentioning pointers, unsigned types (specifically saying it makes no sense to index with a signed type) :)
â Koekje
May 15 at 18:58
2
2
Java arrays are indexed with
int, and there is no size_t in Java ...â Martin R
May 15 at 20:43
Java arrays are indexed with
int, and there is no size_t in Java ...â Martin R
May 15 at 20:43
@MartinR Shame on me. I misread the tag.
â vnp
May 15 at 21:00
@MartinR Shame on me. I misread the tag.
â vnp
May 15 at 21:00
 |Â
show 1 more comment
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f194457%2fbinary-search-for-integers%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
If you added javadocs, you could have added that the
int arrhas to be sorted ;)â RobAu
May 16 at 14:16