【问题标题】:Is there a way to concatenate Java strings in less than O(n) time?有没有办法在少于 O(n) 的时间内连接 Java 字符串?
【发布时间】:2019-09-16 04:07:11
【问题描述】:

我的作业问题涉及以特定顺序连接字符串。我们首先得到字符串,然后是一组指令,告诉我们如何连接它们;最后我们打印输出字符串。

我使用 Kattis FastIO 类来处理缓冲输入和输出。下面是我的算法,它遍历指令以连接字符串。我尝试过制作普通字符串、StringBuffers 和 StringBuilders 的数组。

该程序似乎按预期工作,但由于效率低下,它在我的提交平台上给出了时间限制错误。似乎附加我的方式是 O(n);有没有更快的方法?

public class JoinStrings {
    public static void main(String[] args) {
        Kattio io = new Kattio(System.in, System.out);
        ArrayList<StringBuilder> stringList = new ArrayList<StringBuilder>();
        int numStrings = io.getInt();
        StringBuilder[] stringArray = new StringBuilder[numStrings];

        for (int i = 0; i < numStrings; i++) {
            String str = io.getWord();
            stringArray[i] = new StringBuilder(str);
        }

        StringBuilder toPrint = stringArray[0]; 

        while (io.hasMoreTokens()) {
            int a = io.getInt();
            int b = io.getInt();
            stringArray[a-1].append(stringArray[b-1]); // this is the line that is done N times

            toPrint = stringArray[a-1];
        }

        io.println(toPrint.toString());
        io.flush();
    }
} 

【问题讨论】:

  • stringArray[a-1].append(stringArray[b-1]); 本身就是O(n)。该循环使您的程序在O(n^2) 时间运行。这是因为append(...) 使用了System.arraycopy,这是一种复杂度为O(n) 的本机方法。
  • 我们需要有关该问题的更多信息。结果可以是指数大小(例如,如果您将字符串附加到自身)。如果您必须输出此结果,则您无能为力(StringBuilder 是最有效的解决方案之一)。所以有些假设你没有告诉我们。

标签: java string-concatenation


【解决方案1】:

StringBuilder.append() 将 char 从新字符串复制到现有字符串。它速度很快,但不是免费的。

不是一直将字符串附加到 StringBuilder 数组,而是跟踪需要附加的字符串索引。然后最后追加存储在打印输出索引列表中的字符串。

【讨论】:

  • 是的,我相信最后一点关于跟踪最终的 concat 操作是快速解决这个问题的关键,因为无论如何,Java 中的字符串连接是 O(N) 其中N 是大小两个字符串
  • @smac89 是的。因此,我们不附加字符串,而是仅按附加顺序保留索引列表。字符串越长,我们得到的效率就越高:D
  • 嗯,好的。最后连接所有 N 个字符串实际上更快吗?我觉得如果我迭代字符串集合只是为了连接它们,它会和以前一样复杂吗?
  • @RyanChng,不要做单独的连接。事实上不要做 concats 因为你可能会用完内存。如果这是 C,我建议使用 putc 立即打印每个字符。在 Java 中,请尝试使用 BufferedOutputStream。不过我的建议是避免在打印之前实际连接内存中的所有字符串,因为这只是你的 IO 系统应该通过缓冲区处理的工作的两倍
  • @smac89 谢谢,我开发了一种解决方案,涉及确定索引的顺序(根据 Mạnh Quyết Nguyễn 的建议),然后使用打印功能将它们简单地打印在一行中。它有问题并且无法通过私有测试用例,但在不连接方面做得很好。
猜你喜欢
  • 2020-07-19
  • 2022-01-09
  • 2020-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
相关资源
最近更新 更多