I have this ugly code:
if ( v > 10 ) size = 6;
if ( v > 22 ) size = 5;
if ( v > 51 ) size = 4;
if ( v > 68 ) size = 3;
if ( v > 117 ) size = 2
If you really want the fastest big-O complexity time solution for this particular answer this one is constant lookup.
final int minBoundary = 10;
final int maxBoundary = 145;
final int maxSize = 6;
Vector<Integer> index = new Vector<Integer>(maxBoundary);
// run through once and set the values in your index
subsequently
if( v > minBoundary )
{
size = (v > maxBoundary ) ? maxSize : index[v];
}
What we are doing here is marking all the possible results of v within the range and where they fall, and then we only need to test for boundary conditions.
The issue with this is that it uses more memory and of course if maxBoundary is a lot bigger it will be very space inefficient (as well as take a longer time to initialise).
This may sometimes be the best solution for the situation.
Actually, if the sizes are likely to change, doing it in the database could be a good alternate strategy:
CREATE TABLE VSize (
LowerBound int NOT NULL CONSTRAINT PK_VSize PRIMARY KEY CLUSTERED,
Size int NOT NULL
)
INSERT VSize VALUES (10, 6)
INSERT VSize VALUES (22, 5)
INSERT VSize VALUES (51, 4)
INSERT VSize VALUES (68, 3)
INSERT VSize VALUES (117, 2)
INSERT VSize VALUES (145, 1)
And a stored procedure or function:
CREATE PROCEDURE VSizeLookup
@V int,
@Size int OUT
AS
SELECT TOP 1 @Size = Size
FROM VSize
WHERE @V > LowerBound
ORDER BY LowerBound
int[] arr = new int[] {145, 117, 68, 51, 22, 10};
for(int index = 0; index < arr.length; index++)
{
if(v > arr[index]) return 1 + index;
}
return defaultValue;
7 - (x>10 + x>22 + x>51 + x>68 + x>117 + x>145)
where 7
is the default value (x <= 10
).
Edit: Initially I didn't realize this question is about Java. This expression is not valid in Java, but is valid in C/C++. I will leave the answer, as some users found it helpful.
if ( v > 145 ) size = 1;
else if ( v > 117 ) size = 2;
else if ( v > 68 ) size = 3;
else if ( v > 51 ) size = 4;
else if ( v > 22 ) size = 5;
else if ( v > 10 ) size = 6;
return size;
This is better for your case.
Optionally you should choose Switch Case where ever possible
Update:
If you have analyzed the value of 'v' generally resides in lower range(<10) in most of the cases than you can add this.
if(v < 10) size = SOME_DEFAULT_VALUE;
else if ( v > 145 ) size = 1;
else if ( v > 117 ) size = 2;
else if ( v > 68 ) size = 3;
else if ( v > 51 ) size = 4;
else if ( v > 22 ) size = 5;
else if ( v > 10 ) size = 6;
further :
You can also alter the condition sequence, according to your analysis. If you know that most of the values are less than 10 and then in the second place most of values lie between 68-117, you can alter the condition sequence accordingly.
Edits:
if(v < 10) return SOME_DEFAULT_VALUE;
else if ( v > 145 ) return 1;
else if ( v > 117 ) return 2;
else if ( v > 68 ) return 3;
else if ( v > 51 ) return 4;
else if ( v > 22 ) return 5;
else if ( v > 10 ) return 6;
Yet another variation (less pronounced than the answer by George)
//int v = 9;
int[] arr = {145, 117, 68, 51, 22, 10};
int size = 7; for(;7 - size < arr.length && v - arr[size - 2] > 0; size--) {};
return size;