代码之家  ›  专栏  ›  技术社区  ›  xd1936

如何将一串句子一分为二,分成两个长度尽可能相似的字符串数组?

  •  3
  • xd1936  · 技术社区  · 7 年前

    var a = "A few sentences. For tests. The point of these sentences is to be used as examples.";
    var b = "A couple more sentences. These ones are shorter.";
    var c = "Blah. Foo. Bar. Baz. Test. Test 2. Test C.";
    var d = "Test sentence.";
    

    我想延长期限 string prototype提供了一种方法,可以将每个字符串拆分为两个字符串的数组,每个字符串在数学上具有尽可能相似的字符数,同时保持整个句子。

    我期待的结果是:

    a.halve() // ["A few sentences. For tests.", "The point of these sentences is to be used as examples."]
    b.halve() // ["A couple more sentences.", "These ones are shorter."]
    c.halve() // ["Blah. Foo. Bar. Baz.", "Test. Test 2. Test C."]
    d.halve() // ["Test sentence.", ""]
    

    如果我这样做 a.length / 2 ,我得到了两个字符串的理想目标长度。。。我只是有一段艰难的时光 split ”他说 join 按正确的顺序排列。

    5 回复  |  直到 7 年前
        1
  •  2
  •   Daniel Tran    7 年前

    首先把每件事都分成几个句子。然后找到最佳位置并再次加入。

    var a = "A few sentences. For tests. The point of these sentences is to be used as examples.";
    var b = "A couple more sentences. These ones are shorter.";
    var c = "Blah. Foo. Bar. Baz. Test. Test 2. Test C.";
    var d = "Test sentence.";
    
    String.prototype.halve = function() {
      const ideaLength = this.length / 2;
      const sentences = this.split('.').map(it => it.trim()).filter(it => it != '');
      let current = sentences[0].length + 1;
      let min = Math.abs(current - ideaLength);
      let minPosition = 0;
    
      for (let i = 1; i < sentences.length; i++) {
        current = current + 2 + sentences[i].length;
        const different = Math.abs(ideaLength - current);
        
        if (different < min) {
          min = different;
          minPosition = i;
        }
      }
      
      const first = sentences.slice(0, minPosition + 1).join('. ') + ".";
      const second = sentences.slice(minPosition + 1).join('. ') + ".";
      
      return [first, second === "." ? "" : second];
    }
    
    console.log(a.halve());
    console.log(b.halve());
    console.log(c.halve());
    console.log(d.halve());
        2
  •  1
  •   Timothy Lee    7 年前

    Reflect.set(String.prototype, 'halve', function(){
      let mid = Math.floor(this.length/2)
      let i = mid - 1, j = mid, sep = mid
      while(j<this.length) {
        if(this[i]==='.') { sep = i + 1; break }
        if(this[j]==='.') { sep = j + 1; break }
        i--
        j++
      }
      return [this.slice(0,sep), this.slice(sep)]
    })
    
    var a = "A few sentences. For tests. The point of these sentences is to be used as examples.";
    var b = "A couple more sentences. These ones are shorter.";
    var c = "Blah. Foo. Bar. Baz. Test. Test 2. Test C.";
    var d = "Test sentence.";
    
    console.log(a.halve()) // ["A few sentences. For tests.", "The point of these sentences is to be used as examples."]
    console.log(b.halve()) // ["A couple more sentences.", "These ones are shorter."]
    console.log(c.halve()) // ["Blah. Foo. Bar. Baz.", "Test. Test 2. Test C."]
    console.log(d.halve()) // ["Test sentence.", ""]
    
        3
  •  1
  •   Akrion    7 年前

    这可以通过找出中间位置来解决 indexOf lastIndexOf :

    var a = "A few sentences. For tests. The point of these sentences is to be used as examples.";
    var b = "A couple more sentences. These ones are shorter.";
    var c = "Blah. Foo. Bar. Baz. Test. Test 2. Test C.";
    var d = "Test sentence.";
    var e = "A. B. C. D. E. F. G. H. The point of these sentences is to be used as examples."
    var f = "The point of these sentences is to be used as examples. A. B. C. D. E. F. G. H."
    
    const half = str => {
      let middle = Math.floor(str.length / 2)
      let nextDot = str.lastIndexOf('.', middle)
      nextDot = nextDot <= 0 ? str.indexOf('.', middle)+1 : nextDot+1
      return [str.substr(0, nextDot), str.substr(nextDot, str.length).trim()]
    }
    
    console.log(half(a))
    console.log(half(b))
    console.log(half(c))
    console.log(half(d))
    console.log(half(e))
    console.log(half(f))

    lastIndexOf 索引 为了找出你需要在中间位置朝哪个方向走。一旦你得到了中间,那么它就是在使用 substr 去拿碎片。

        4
  •  0
  •   Spangle    7 年前

    下面也完成了工作。它将根据何时有“”将句子拆分为数组。使用这个新数组,您可以使用Math.floor()获得数组的中间部分,并对其进行取整。然后,一些条件将对事情进行排序。

    var a = "A few sentences. For tests. The point of these sentences is to be used as examples.";
    var b = "A couple more sentences. These ones are shorter.";
    var c = "Blah. Foo. Bar. Baz. Test. Test 2. Test C.";
    var d = "Test sentence.";
    
    function splitString(str){
        var workSplit = str.split(" ");
        var midPoint = Math.floor(workSplit.length / 2);
        var result = [[],[]];
        for(var char in workSplit){
            if(char < midPoint){
                result[0].push(workSplit[char])
            } else {
                result[1].push(workSplit[char]);
            }
        }
        return [result[0].join(" "), result[1].join(" ")]
    }
    
    console.log(splitString(a));
    console.log(splitString(b));
    console.log(splitString(c));
    console.log(splitString(d));
    
        5
  •  0
  •   Bedo    7 年前

    首先,使用此答案查找字符串中出现的所有“.”。

    然后,找到最靠近中间的点,并将其拆分(例如,使用此处的答案: split string in two on given index and return both parts )

    一些代码:

    function splitValue(value, index) {
      return [value.substring(0, index), value.substring(index)];
    }
    
    function splitStringInTwo(str) {
      const half = Math.trunc(str.length / 2);
      let slicePoint = {position: -1, distance: 9999};
    
      if (str.indexOf('.')  === -1) {
        return splitValue(str, str.length / 2);
      }
    
      for (let i = 1; i > 0; i =  str.indexOf('.', i) + 1) {
        if (Math.abs(i - half) < slicePoint.distance) {
          slicePoint = {position: i, distance: Math.abs(i - half)}; // Distance is shrinking, save it.
        } else {
          return splitValue(str, slicePoint.position); // Distance it growing. Stop.
        }
      }
    
    
    }
    
    const myString = "Here is a first string. My second, though, is larger by a fair amount of characters. I don't want it to be split.";
    
    console.log(splitStringInTwo(myString));