从整数转换为十六进制字符串以检查是否包含一个单词

huangapple go评论68阅读模式
英文:

Convert from int to hexadecimal string to check if it contains a word

问题

我们正在做以下的编程练习[Death by Coffee][1]

主要任务是将整数转换为十六进制并进行值的相加我们编写了以下代码

    public class Dinglemouse {
    
      public static int[] coffeeLimits /*☕*/ (final int year, final int month, final int day) {
        System.out.println("year: "+year);
        System.out.println("month: "+month);
        System.out.println("day: "+day);
        
        long healthNumber = Long.parseLong(String.valueOf(year)+String.valueOf(month)+String.valueOf(day));
        System.out.println("healthNumber: "+healthNumber);
        
        long cafe = Long.valueOf("CAFE",16);
        long decaf = Long.valueOf("DECAF",16);
        
        int cafeLimit = getLimit(cafe, healthNumber);
        System.out.println("\ncafeLimit: "+cafeLimit);
        int decafLimit = getLimit(decaf, healthNumber);
        System.out.println("\ndecafLimit: "+decafLimit);
        
        return new int []{cafeLimit, decafLimit};
      }
    
      public static int getLimit(long coffee, long healthNumber){
        int limit=0;
        while(limit<=5000 && !Long.toHexString(healthNumber).contains("dead")){
          limit++;
          healthNumber+=coffee;
          System.out.println("new healthNumber: "+Long.toHexString(healthNumber));
        }
        return limit>5000 ? 0 : limit;    
      }
    
    }


我们想知道为什么代码通过以下的测试除了 exJohn

    import org.junit.Test;
    import static org.junit.Assert.*;
    import java.util.*;
    
    public class Tests {
      
      // Show returned limits
      private static int[] show(final int y, final int m, final int d, final int[] result) {
        System.out.println(String.format("%4d%02d%02d -> ",y,m,d)+Arrays.toString(result));
        return result;
      }
      
      @Test
      public void exJohn() {
        final int y=1950, m=1, d=19;
        assertArrayEquals(new int[]{2645,1162}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
      }
      
      @Test
      public void exSusan() {
        final int y=1965, m=12, d=11;
        assertArrayEquals(new int[]{111,0}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
      }
    
      @Test
      public void exElizabeth() {
        final int y=1964, m=11, d=28;
        assertArrayEquals(new int[]{0,11}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
      }
    
      @Test
      public void exPeter() {
        final int y=1965, m=9, d=4;
        assertArrayEquals(new int[]{0,0}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
      }
      
    }


我们已经打印出在 `getLimit` 循环内部得到的内容我们发现咖啡限制的最后一个 `healthNumber` 输出为

    ...
    new healthNumber: 2dc4cbb
    new healthNumber: 2dd17b9
    new healthNumber: 2dde2b7
    new healthNumber: 2deadb5
    
    cafeLimit: 889


而对于无咖啡因限制我们有

    ...
    new healthNumber: 10ff8a241
    new healthNumber: 110068ef0
    new healthNumber: 110147b9f
    new healthNumber: 11022684e
    
    decafLimit: 0

因此我们的代码结果是
[889, 0]

而实际上应该是
[2645, 1162]


我们认为可能是整数溢出导致的因此我们将所有变量都更改为 long但程序的行为仍然相同


我们已阅读过

 - [https://stackoverflow.com/questions/9321553/java-convert-integer-to-hex-integer](https://stackoverflow.com/questions/9321553/java-convert-integer-to-hex-integer)
 - [https://stackoverflow.com/questions/5258415/how-to-get-a-hex-value-from-a-decimal-integer-in-java](https://stackoverflow.com/questions/5258415/how-to-get-a-hex-value-from-a-decimal-integer-in-java)
 - [https://stackoverflow.com/questions/11194513/convert-hex-string-to-int](https://stackoverflow.com/questions/11194513/convert-hex-string-to-int)

  [1]: [https://www.codewars.com/kata/57db78d3b43dfab59c001abe](https://www.codewars.com/kata/57db78d3b43dfab59c001abe)
英文:

we are doing the following programming exercise: Death by Coffee.

The main task is to convert from integers to hexadecimals and add values. We have written the following code:

public class Dinglemouse {
public static int[] coffeeLimits /*☕*/ (final int year, final int month, final int day) {
System.out.println(&quot;year: &quot;+year);
System.out.println(&quot;month: &quot;+month);
System.out.println(&quot;day: &quot;+day);
long healthNumber = Long.parseLong(String.valueOf(year)+String.valueOf(month)+String.valueOf(day));
System.out.println(&quot;healthNumber: &quot;+healthNumber);
long cafe = Long.valueOf(&quot;CAFE&quot;,16);
long decaf = Long.valueOf(&quot;DECAF&quot;,16);
int cafeLimit = getLimit(cafe, healthNumber);
System.out.println(&quot;\ncafeLimit: &quot;+cafeLimit);
int decafLimit = getLimit(decaf, healthNumber);
System.out.println(&quot;\ndecafLimit: &quot;+decafLimit);
return new int []{cafeLimit, decafLimit};
}
public static int getLimit(long coffee, long healthNumber){
int limit=0;
while(limit&lt;=5000 &amp;&amp; !Long.toHexString(healthNumber).contains(&quot;dead&quot;)){
limit++;
healthNumber+=coffee;
System.out.println(&quot;new healthNumber: &quot;+Long.toHexString(healthNumber));
}
return limit&gt;5000 ? 0 : limit;    
}
}

We wonder why the code passes the following tests, except exJohn:

import org.junit.Test;
import static org.junit.Assert.*;
import java.util.*;
public class Tests {
// Show returned limits
private static int[] show(final int y, final int m, final int d, final int[] result) {
System.out.println(String.format(&quot;%4d%02d%02d -&gt; &quot;,y,m,d)+Arrays.toString(result));
return result;
}
@Test
public void exJohn() {
final int y=1950, m=1, d=19;
assertArrayEquals(new int[]{2645,1162}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
}
@Test
public void exSusan() {
final int y=1965, m=12, d=11;
assertArrayEquals(new int[]{111,0}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
}
@Test
public void exElizabeth() {
final int y=1964, m=11, d=28;
assertArrayEquals(new int[]{0,11}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
}
@Test
public void exPeter() {
final int y=1965, m=9, d=4;
assertArrayEquals(new int[]{0,0}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
}
}

We have printed what we get inside getLimit's loop, and we see that the last healthNumber being output for cafe limit is:

...
new healthNumber: 2dc4cbb
new healthNumber: 2dd17b9
new healthNumber: 2dde2b7
new healthNumber: 2deadb5
cafeLimit: 889

And for the decaf limit we have:

...
new healthNumber: 10ff8a241
new healthNumber: 110068ef0
new healthNumber: 110147b9f
new healthNumber: 11022684e
decafLimit: 0

So then our code's result is:
[889, 0]

When it should be:
[2645, 1162]

We thought it could be caused by int overflow so we changed all variables to long, however the program behaves equal.

We have read:

答案1

得分: 0

以下是您要求的翻译内容:

您的代码行

long healthNumber = Long.parseLong(String.valueOf(year)+String.valueOf(month)+String.valueOf(day));

中的 "eats" 掉了日期和月份前面的零,您可以将其替换为类似以下方式:

long healthNumber = year*10000+month*100+day;

以使其按预期工作。

英文:

Your line of code

long healthNumber = Long.parseLong(String.valueOf(year)+String.valueOf(month)+String.valueOf(day));

"eats" leading zeroes in day and month, you can replace it with something like

long healthNumber = year*10000+month*100+day;

to make it work as expected.

huangapple
  • 本文由 发表于 2020年4月10日 17:34:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/61137539.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定