【问题标题】:JAVA string how can i implement the length methodJAVA字符串如何实现长度方法
【发布时间】:2014-09-28 08:39:40
【问题描述】:

我室友的老师给了他们一个用JAVA实现字符串长度方法的作业? 我们想出了两种方法。

  1. 检查元素,当得到越界异常时,表示字符串结束,我们捕获这个异常,然后我们可以得到长度。

  2. 每传一个字符串计算长度,我们都会在它的末尾加上特殊字符,可以是'\0',也可以是“A”等。

    李>

但我们都认为这两种方式可能可以完成任务,但它们是不好的(或坏习惯做例外),并不酷。

我们已经用谷歌搜索过了,但没有得到我们想要的。

【问题讨论】:

  • 分配没有任何意义。不管你如何“实现”它,包括你的两次尝试和到目前为止给出的所有答案,它总是隐含地依赖于String 已经知道它的长度这一事实。因此,无论看起来如何,该解决方案总是使用已知长度来做一些花哨的事情,以隐藏它最终重建了最初已经给出的长度。

标签: java string overwrite string-length


【解决方案1】:

这样的?

int i = 0;
for (char ch : string.toCharArray()) {
  i++;
}

【讨论】:

  • 但你如何确定是否结束?
  • 因为foreach 循环被定义为只遍历数组中的每个元素一次。这是在不使用 String.length() 方法的情况下计算字符串长度问题的合理解决方案(尽管有更简单的方法)。它确实有需要额外 O(n) 内存的缺点。对于小字符串,这不是问题。对于非常大的字符串,它可能是。
  • OK.i.m 对更简单的方法感到好奇
  • @myqiqiang - 请参阅我的回答中的编辑。获得 char[] 后,无需遍历它即可获得长度。
【解决方案2】:

你可能想要的伪代码是:

counter = 0
for(Character c in string) {
    counter = counter + 1
}

这需要您找到一种方法将 Java String 转换为字符数组。

【讨论】:

    【解决方案3】:

    教师可能正试图让他或她的学生思考,并且会对解决问题的创造性解决方案感到满意。

    这些解决方案都不会在现实世界中使用,因为我们有String.length() 方法。但是您正在学习的创造性、解决问题的过程将用于实际开发。

    "1.检查元素,当得到越界异常时,表示字符串结束,我们捕获这个异常,然后我们可以得到长度。"

    在这里,您会在正常情况下引发异常。一个常见的风格准则是仅在异常情况下才抛出异常。与正常的控制流相比,抛出异常可能更昂贵且更难被人类遵循。

    也就是说,您的这个想法对于非常长的字符串具有潜在优势。到目前为止,所有发布的答案都在线性时间和空间中运行。它们执行所花费的时间和/或额外空间与字符串的长度成正比。 使用这种方法,您可以实现对字符串长度的 O(log n) 搜索。

    无论是否线性,老师都可能会发现这种方法的创造性是可以接受的。如果老师已经传达了例外仅适用于特殊情况的想法,请避免使用。

    "2. 每次传一个字符串计算长度,我们在其末尾添加特殊字符,可以是'\0',或者"A"等。"

    这个想法有缺陷。如果字符串中包含您的特殊字符会怎样?

    编辑

    一个简单的实现是使用String.toCharArray() 获取底层char 数组的副本,然后简单地获取它的长度。与您的想法不同,这不是就地方法 - 制作副本需要额外的内存空间。

        String s = "foo";
        int length = s.toCharArray().length;
    

    【讨论】:

    • 为什么你认为第一种方法有O(log(n))?因为它站在那里“当得到越界异常时,它意味着字符串的结尾”它意味着一个线性搜索
    • @Holger - 我认为 OP 可能隐含地指的是字符串的线性遍历。但是 OP 明确地 指的是检查字符串元素的一般思想,这可以以非线性的 O(log n) 方式完成。
    • 您似乎在谈论二进制搜索,但由于您不知道长度,您需要扫描整个 2³¹ 搜索空间。太好了,这意味着该算法甚至是 O(1),因为它不依赖于 String 的长度,但生成并捕获多达 31 个异常也意味着正常的无异常线性搜索可能会更快,即使对于最长Strings。一个很好的例子来说明O(…) 符号的局限性。
    • @Holger - 你是对的,使用抛出异常的方法,每个元素的常数因子会显着提高。但我怀疑您高估了 31 个异常与 2^31 个检查访问器调用的成本。现在测试...
    • 它可能在很大程度上取决于 JVM 版本,当然还有要跟踪的实际堆栈的深度。过去,异常非常缓慢,因为它们应该是异常的,例如JVM 甚至没有尝试将异常处理程序交给 JIT。相比之下,线性搜索代码对于 JVM 来说是完全可优化的。
    【解决方案4】:

    试试这个

    public static int Length(String str) {
        str = str + '\0';
        int count = 0;
    
        for (int i = 0; str.charAt(i) != '\0'; i++) {
            count++;
        }
    
        return count;
    }
    

    【讨论】:

    • 这是我的第二种方式。在字符串末尾添加\0
    【解决方案5】:

    怎么样:

    "your string".toCharArray().length
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-14
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      • 2011-01-15
      • 2010-10-23
      • 2014-07-30
      相关资源
      最近更新 更多