Get rid of ugly if statements

2019-01-10 02:31发布

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 ( v > 145 ) size = 1;
return size;

How can I get rid of the multiple if statements?

25条回答
Juvenile、少年°
2楼-- · 2019-01-10 03:12
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.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-01-10 03:13
return (v-173) / -27;
查看更多
老娘就宠你
4楼-- · 2019-01-10 03:13

Is there an underlying mathematical rule to this? If so you should use that: but only if it comes from the problem domain, not just some formula that happens to fit the cases.

查看更多
对你真心纯属浪费
5楼-- · 2019-01-10 03:18

You could rewrite it in ARM code. It's only 7 cycles worst case and a slender 164 bytes. Hope that helps. (note: this is untested)

; On entry
;   r0 - undefined
;   r1 - value to test
;   lr - return address
; On exit
;   r0 - new value or preserved
;   r1 - corrupted
;
wtf
        SUBS    r1, r1, #10
        MOVLE   pc, lr
        CMP     r1, #135
        MOVGT   r0, #1
        ADRLE   r0, lut
        LDRLEB  r0, [r0, r1]
        MOV     pc, lr
;
; Look-up-table
lut
        DCB     0   ; padding
        DCB     6   ; r1 = 11 on entry
        DCB     6
        DCB     6
        DCB     6
        DCB     6
        DCB     6
        DCB     6
        DCB     6
        DCB     6
        DCB     6
        DCB     6
        DCB     6
        DCB     5   ; r1 = 23 on entry
        DCB     5
        ...
        ALIGN
查看更多
放我归山
6楼-- · 2019-01-10 03:19
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楼-- · 2019-01-10 03:19

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
查看更多
登录 后发表回答