【问题标题】:Replace one set of characters with another set of characters用另一组字符替换一组字符
【发布时间】:2020-08-03 01:57:56
【问题描述】:

我正在编写将罗马数字转换为十进制数字的代码。

我想知道这条线是否可以优化?

String s = "MCMXCIV";
String code = s.replaceAll("I", "a")
               .replaceAll("V", "b")
               .replaceAll("X", "c")
               .replaceAll("L", "d")
               .replaceAll("C", "e")
               .replaceAll("D", "f")
               .replaceAll("M", "g");

code 的预期值:gegceab

编辑 1:可以用更短的方式编写相同的代码吗?

编辑 2

我想要的两个条件

  1. 避免昂贵的字符串连接
  2. O(1)中的对应代码替换每个字符

【问题讨论】:

标签: java replaceall


【解决方案1】:

我不知道这如何帮助您将罗马数字转换为十进制数字,但是,当然,这可以简化!

对于初学者来说,.replace 在这项工作上做得更好('replaceAll 是一个愚蠢的名字;第一个参数是一个正则表达式。replace,没有 all, 替换 all , 并接受一个实际的原始字符串,这正是你想要的——java 不喜欢破坏向后兼容性;这个愚蠢的名字不太可能被纠正)。

其次,“更短”几乎没有意义。编写代码时的相关目标是可读性和灵活性,很少有效率(性能);更短本身并不是一个相关的目标。

这是另一种选择;对于大字符串来说,它的效率要高得多。对于小字符串,现在是 2020 年,所花费的时间将向下舍入到 0。

private static final String LETTERS = "IVXLCDM";

char[] cs = s.toCharArray();
for (int i = 0; i < cs.length; i++) {
    cs[i] = 'a' + LETTERS.indexOf(cs[i]);
}
String code = new String(cs);

【讨论】:

  • 感谢您的回答。我有一个问题,indexOf 方法不会采用O(n) 吗?
  • O(n) 其中n 是常数7O(1)
  • 我实际上使用了一个运行良好的 HashMap。我错过了LETTERS 是最终的事实,并且需要持续的时间来搜索。在我看来,在我的情况下,使用字符串比使用 HashMap 更好。
  • 更新:使用字符串后运行时从5ms to 3ms更改为40.4MB to 39.3MB
  • 这些数字毫无意义,您的输入字符串很可能太短了(如果它们的长度不超过 10000 个字符,您永远不会注意到)。 HashMap 比 7 长度字符串上的 indexOf 慢几个数量级。整个 O(n) 的事情根本不适用,直到您获得大量数据。
【解决方案2】:

您可以使用两个数组并循环遍历它们,将from[i] 替换为to[i]

String s = "MCMXCIV";
char[] from = new char[]{'I', 'V', 'X', 'L', 'C', 'D', 'M'};
char[] to = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g'};

for (int i = 0; i < from.length; i++){
    s = s.replace(from[i], to[i]);
}

【讨论】:

  • 您可能希望使用Map,其中键是from 字符,值是to 字符。这样您就可以更轻松地保持一致的数据并确保 1:1 关系。
  • @akuzminykh 我考虑过,但实际上它只会使代码更加复杂,而不会使其比 OP 的原始代码更短。我认为在这种情况下将字符放在char[]String 中是更好的选择。
猜你喜欢
  • 2013-07-11
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-08
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
相关资源
最近更新 更多