Я встретил приведенный ниже код в ответе на вопрос о разбиении строк по длине относительно ближайшего пробела , в котором решение дано в C #, в котором используетсяyield return
.Однако я ищу решение Java, поэтому не могу использовать yield return
.(Хотя есть библиотека yielder
, я не уверен, как использовать ее для адаптации кода C #.)
Код C # Дмитрия Быченко приведен ниже:
// Enumerate by nearest space
// Split String value by closest to length spaces
// e.g. for length = 3
// "abcd efghihjkl m n p qrstsf" -> "abcd", "efghihjkl", "m n", "p", "qrstsf"
public static IEnumerable<String> EnumByNearestSpace(this String value, int length) {
if (String.IsNullOrEmpty(value))
yield break;
int bestDelta = int.MaxValue;
int bestSplit = -1;
int from = 0;
for (int i = 0; i < value.Length; ++i) {
var Ch = value[i];
if (Ch != ' ')
continue;
int size = (i - from);
int delta = (size - length > 0) ? size - length : length - size;
if ((bestSplit < 0) || (delta < bestDelta)) {
bestSplit = i;
bestDelta = delta;
}
else {
yield return value.Substring(from, bestSplit - from);
i = bestSplit;
from = i + 1;
bestSplit = -1;
bestDelta = int.MaxValue;
}
}
// String's tail
if (from < value.Length) {
if (bestSplit >= 0) {
if (bestDelta < value.Length - from)
yield return value.Substring(from, bestSplit - from);
from = bestSplit + 1;
}
if (from < value.Length)
yield return value.Substring(from);
}
}
...
var list = data.EnumByNearestSpace(150).ToList();
Мой код Java приведен ниже, но он неверен.(Он разделяет только первую строку, но вместо последующих строк я получаю одну длинную строку.)
public static List<String> splitStringByNearestSpace(String text, int length) {
List<String> parts = new ArrayList<String>();
if (null != text && !text.isEmpty()) {
int bestDelta = Integer.MAX_VALUE, bestSplit = -1, from = 0;
for (int i = 0; i < length; i++) {
char ch = text.charAt(i);
if (ch == ' ') continue;
int size = (i - from);
int delta = (size - length > 0)? size - length : length - size;
if (bestSplit < 0 || delta < bestDelta) {
bestSplit = i;
bestDelta = delta;
} else {
parts.add(text.substring(from, bestSplit - from));
i = bestSplit;
from = i + 1;
bestSplit = -1;
bestDelta = Integer.MAX_VALUE;
}
}
// String's tail
if (from < text.length()) {
if (bestSplit >= 0) {
if (bestDelta < text.length() - from) {
parts.add(text.substring(from, bestSplit - from)); // should yield return
from = bestSplit + 1;
}
if (from < text.length()) {
parts.add(text.substring(from)); // should yield return
}
}
}
}
return parts;
}
Тестовый вызов:
String lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
+ "Aliquam nec ultrices tellus. Vivamus accumsan justo in orci fermentum "
+ "maximus. Cras id condimentum felis, iaculis finibus sapien. Fusce tempor,"
+ " lectus id hendrerit interdum, mauris ex ultrices leo, et mattis nibh "
+ "purus sit amet leo. Etiam ac dolor lorem. Morbi odio ligula, ultrices "
+ "vitae risus id, pretium iaculis odio. Curabitur vel sapien tristique, "
+ "dictum sapien ut, dignissim felis. Aliquam iaculis fermentum mattis.";
List<String> chunks = splitStringByNearestSpace(lipsum, 78);
if (chunks.size() > 0) {
for (String s : chunks) {
System.out.println(s + " => " + s.length());
}
} else {
System.err.println("No chunks returned!");
}