Как разбить строку предложений пополам, на массив из двух строк, каждая из которых имеет максимально возможную длину? - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть интересная проблема здесь.У меня есть пара строк Javascript, например, так:

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, чтобы иметь метод для разделения каждой строки на массив из двух строк, каждая из которых имеет одинаковое числосимволов как математически возможно, при этом сохраняя целые предложения.

Результаты, которые я бы искал:

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, я получу идеальную целевую длинудве строки ... Мне просто тяжело splitjoin в правильном порядке.

Ответы [ 5 ]

0 голосов
/ 06 декабря 2018

Эту проблему можно решить, выяснив, где находится середина, через 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 и indexOf, чтобы выяснить, в каком направлении вам нужно двигаться с точки зрения средней позиции.Как только вы получите эту середину, она просто использует substr, чтобы получить кусочки.

0 голосов
/ 06 декабря 2018

Во-первых, используйте этот ответ, чтобы найти все случаи "."в вашей строке.

Затем найдите точку, ближайшую к вашей середине, и разбейте ее там (например, используя ответ здесь: разбейте строку на два по заданному индексу и верните обе части )

Какой-то код:

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));
0 голосов
/ 06 декабря 2018

Ниже также выполнено задание.Это разделит предложение на массив в зависимости от того, когда есть "".Используя этот новый массив, вы можете использовать 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));
0 голосов
/ 06 декабря 2018

Быстрое решение:)

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.", ""]
0 голосов
/ 06 декабря 2018

Сначала разбейте все на предложения.Затем найдите лучшую позицию и присоединитесь снова.

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());
...