如何在线性时间内附加字符串

时间:2018-07-11 21:00:58

标签: javascript string concatenation big-o

我想将在字符组之间随机包含破折号的字符串更改为在n个字符组之间具有破折号的字符串。我想将其保持在O(n)时间复杂度的最坏情况下。下面的soln可以工作,但是我认为字符串连接很慢,并且为了保持O(n),希望使用恒定时间的操作。

//Desired string is 15-678435-555339

let s = "1-5678-43-5555-339"
let newString = ""
let counter = 0
let n = 6

if(s.length === 1 || s.length < k) return s
for(let i = s.length-1; i >= 0; i--){
    if(counter === 6) {
        counter = 0;
        newString = "-" + newString
    }

    if(s.charAt(i) !== "-") {
        counter += 1
        newString = s.charAt(i) + newString
    }
} 

3 个答案:

答案 0 :(得分:1)

不确定您使用的是哪种语言,但是大多数人都具有StringBuilder的概念,该概念只是作为字符串的ArrayList实现,并在您要求生成的字符串时串联在一起-通常通过toString()方法。< / p>

这是一个Java示例:https://ideone.com/vHHdHH

public static void main(String[] args) {

  String s = "1-5678-43-5555-339";
  StringBuilder sb = new StringBuilder();
  int dashPosition = 2;
  int count = 0;

  char[] ch = s.toCharArray();

  for (int i = 0; i < ch.length; i++) {
    if (Character.getNumericValue(ch[i]) != -1) {
      sb.append(ch[i]);
      count++;
      if (count % dashPosition == 0) {
        sb.append('-');
        count = 0;
        dashPosition = 6;
      }
    }
  }
  if (sb.charAt(sb.length() - 1) == '-') {
    sb.deleteCharAt(sb.length() - 1);
  }

  //Desired string is 15-678435-555339
  System.out.println(sb.toString());

}

答案 1 :(得分:1)

因为这是javascript,通常可以用最少的代码获得性能最高的解决方案,即:

function* chunk(iterable, size) {
  for(let i = iterable.length; i >= 0; i -= size)
    yield iterable.slice(Math.max(0, i - size), i);
}

let result = [...chunk(s.replace(/-/g, ""), 6)].reverse().join("-");

(但这只是猜测,在很大程度上取决于引擎)

  

嗯,我认为字符串concat很昂贵,使其远高于o(n)。

通常是的,但是一些非常激进的内联可能会将其优化。

答案 2 :(得分:1)

如果这是一个现实生活中的问题,而不是带有任意约束的作业,则应将字符串连接起来。在现代javascript上,尤其是对于像您已经到达那里的短字符串,在正常情况下这不会出现性能问题。

如果您确实想减少创建的字符串的数量,则可以使用.charCodeAt(i)构造一个整数的字符代码数组,然后使用s = String.fromCharCode.apply(null,arrayOfIntegers)。但这不是您通常必须要做的。