【问题标题】:Recursive method to determine if a string is a hex number - Java确定字符串是否为十六进制数字的递归方法 - Java
【发布时间】:2011-08-06 14:07:20
【问题描述】:

这是一个家庭作业问题,我遇到了一些麻烦。

编写一个递归方法来确定一个字符串是否是一个十六进制数。 为您的方法编写 javadocs。 如果每个字符都是 0 或 1 或 2 或 3 或 4 或 5 或 6 或 7 或 8 或 9 或 a 或 A 或 b 或 B 或 c 或 C 或 d 或 D 或 e 或 E 或 f 或 f。

目前我所能看到的测试是如果字符串 0 处的字符是他给我的这些值之一,那么它的那部分是十六进制。

有什么提示或建议可以帮助我吗?

这是我目前所拥有的:`

public boolean isHex(String string){


    if (string.charAt(0)==//what goes here?){
        //call isHex again on s.substring(1)
    }else return false;
    }

`

【问题讨论】:

  • 你在正确的轨道上。查找 String.substring 并考虑如何设置对字符串中所有字符的递归检查。
  • 请发布您的代码,我们可以看看它有什么问题。
  • @sverre 我在 uni 也有类似的情况(我们不是吗?),我的助教试图告诉我我的方法很差,因为它使用了 String.substring() 解释它是我的方法 @ 987654323@。我和教授一起讨论了这个问题(用 String 类的源代码来证明我的情况。)希望 Joel 的助教不要那么天真! :-)
  • @glowcoder:我看不出 TA 会怎么做。 string.substring() 创建一个新字符串,除非结果是原始字符串。因此,由于您的方法将被调用 n 次,并且每个会复制 O(n) 个字符,因此需要 O(n*n)。
  • @Voo 那是他犯的错误。在 Java 中,substring 是 O(1)。它不会复制字符。结果字符串使用相同的底层char[]。它所改变的只是开始和偏移指针(实际上不是指针,只是ints 指定了索引。)

标签: java methods recursion hex


【解决方案1】:

由于这是作业,我只给出一些提示而不是代码:

编写一个方法,如果满足要求,则始终测试字符串的第一个字符。如果不是,则返回 false,如果是,则使用相同的 String 再次调用该方法,但缺少第一个字符。如果它只剩下 1 个字符并且它也是一个十六进制字符,则返回 true。

伪代码:

public boolean isHex(String testString) {


   If String has 0 characters -> return true;

   Else

      If first character is a hex character -> call isHex with the remaining characters

      Else if the first character is not a hex character -> return false;

}

【讨论】:

  • 我能够在我的代码中做到这一点,但我遇到的麻烦就在这部分。 “如果第一个字符是十六进制字符”我是否必须创建类似 if(s.charAt(0)=='A') 再次调用 isHex 但我必须为 AF 和从 0-9 执行此操作吗?
  • 最简单的测试方法可能是: if (s.subString(0,1).equals("A") || s.subString(0,1).equals("B" ) ....)
  • 哦,好的。我试图避免这种情况,但我想我必须这样做。
  • @Joel 请参阅我的答案以更好地检查 hexDigit。我以为你正在寻找一个大纲来检查 hexString。
【解决方案2】:

听起来您应该递归地迭代字符串中的字符,并通过递归调用返回当前字符是否在 [0-9A-Fa-f] 中的布尔 AND...

【讨论】:

    【解决方案3】:

    如果您正在寻找一个好的十六进制数字方法:

    boolean isHexDigit(char c) {
        return Character.isDigit(c) || (Character.toUpperCase(c) >= 'A' && Character.toUpperCase(c) <= 'F');
    }
    

    根据要求提供提示或建议:

    1. 所有递归方法都使用不同的输入调用自己(好吧,希望是不同的输入!)
    2. 所有递归方法都有一个停止条件。

    你的方法签名应该是这样的

    boolean isHexString(String s) {
        // base case here - an if condition
    
        // logic and recursion - a return value
    
    }
    

    另外,不要忘记十六进制字符串可以以“0x”开头。这可能(更)难做到,所以我会先让常规功能工作。如果您稍后处理它,请记住 0xABCD0x123 不应通过。 :-)

    关于子字符串:直接来自String类源:

    public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > count) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    if (beginIndex > endIndex) {
        throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    }
    return ((beginIndex == 0) && (endIndex == count)) ? this :
        new String(offset + beginIndex, endIndex - beginIndex, value);
    }
    

    offset是int类型的成员变量

    value是char[]类型的成员变量

    它调用的构造函数是

    String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
    }
    

    这显然是一个 O(1) 的方法,调用了一个 O(1) 的构造函数。它可以做到这一点,因为 String 是不可变的。您不能更改字符串的值,只能创建一个新字符串。 (让我们省略诸如反射和sun.misc.unsafe之类的东西,因为它们是无关的解决方案!)由于它无法更改,您也不必担心其他线程会弄乱它,所以像这样传递是完全可以的乡村自行车。

    【讨论】:

    • @ikegami 考虑传入0xx123。不是有效的十六进制字符串。 1230x456 也不是。但是,由于0x456 是,并且假设您的算法通过了该测试,当您关闭123 时,您将留下0x456,但您希望返回false。这是一个(稍微)更具挑战性的问题,但它仍然是一个问题。
    • 是的,在上面看到了您的评论,并且已经删除了错误的第一条评论。我保持纠正:)
    【解决方案4】:

    当递归解决问题时,您通常希望解决一小部分(“基本情况”),然后对其余部分进行递归。

    您已经弄清楚了基本情况 - 检查单个字符是否为十六进制。

    现在您需要“递归其余部分”。

    这里有一些用于反转字符串的伪代码(Python-ish) - 希望您会看到类似的方法可以如何应用于您的问题(实际上,所有递归问题)

    def ReverseString(str):
        # base case (simple)
        if len(str) <= 1:
            return str
    
        # recurse on the rest...
        return last_char(str) + ReverseString(all_but_last_char(str))
    

    【讨论】:

      【解决方案5】:

      您已经收到了很多有用的答案。如果您想进一步训练您的递归技能(以及一般的 Java 技能),我建议您访问Coding Bat。您会发现很多练习以及自动化测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-13
        • 1970-01-01
        • 2012-07-10
        • 2012-07-20
        • 2017-03-04
        • 2013-02-02
        • 2019-07-27
        • 1970-01-01
        相关资源
        最近更新 更多