JAVA - вставка новой строки в следующем пробеле после 30 символов - PullRequest
3 голосов
/ 23 июня 2009

У меня большой блок текста (200+ символов в строке) и мне нужно вставить новые строки в следующем пробеле после 30 символов, чтобы сохранить слова. Вот что у меня сейчас (НЕ работает):

String rawInfo = front.getItemInfo(name);
String info = "";
int begin = 0;
for(int l=30;(l+30)<rawInfo.length();l+=30) {
    while(rawInfo.charAt(l)!=' ')
        l++;
    info += rawInfo.substring(begin, l) + "\n";
    begin = l+1;
    if((l+30)>=(rawInfo.length()))
        info += rawInfo.substring(begin, rawInfo.length());
}

Спасибо за любую помощь

Ответы [ 6 ]

18 голосов
/ 23 июня 2009

Как предполагает kdgregory, использование StringBuilder, вероятно, будет более простым способом работы со строками.

Поскольку я не совсем уверен, является ли число символов до вставки новой строки словом до или после 30 символов, я решил использовать слово после 30 символов, поскольку реализация, вероятно, проще.

Подход заключается в том, чтобы найти экземпляр " ", который появляется по крайней мере через 30 символов после текущего символа, который просматривается, с помощью StringBuilder.indexOf. Когда появляется пробел, \n вставляется StringBuilder.insert.

(Мы будем предполагать, что новая строка здесь \n - фактический разделитель строк, используемый в текущей среде, можно получить с помощью System.getProperty("line.separator");).

Вот пример:

String s = "A very long string containing " +
    "many many words and characters. " +
    "Newlines will be entered at spaces.";

StringBuilder sb = new StringBuilder(s);

int i = 0;
while ((i = sb.indexOf(" ", i + 30)) != -1) {
    sb.replace(i, i + 1, "\n");
}

System.out.println(sb.toString());

Результат:

A very long string containing many
many words and characters. Newlines
will.

Я должен добавить, что приведенный выше код не был протестирован, за исключением примера String, который я показал в коде. Не было бы слишком удивительно, если бы это не работало при определенных обстоятельствах.

Редактировать

Цикл в примере кода заменен циклом while, а не циклом for, который не очень подходит в этом примере.

Кроме того, метод StringBuilder.insert был заменен методом StringBuilder.replace, как Кевин Стич отметил в комментариях, что вместо * используется метод replace 1046 * чтобы получить желаемое поведение.

4 голосов
/ 23 июня 2009

Вот решение, основанное на тестировании.

import junit.framework.TestCase;

public class InsertLinebreaksTest extends TestCase {
    public void testEmptyString() throws Exception {
        assertEquals("", insertLinebreaks("", 5));
    }

    public void testShortString() throws Exception {
        assertEquals("abc def", insertLinebreaks("abc def", 5));
    }

    public void testLongString() throws Exception {
        assertEquals("abc\ndef\nghi", insertLinebreaks("abc def ghi", 1));
        assertEquals("abc\ndef\nghi", insertLinebreaks("abc def ghi", 2));
        assertEquals("abc\ndef\nghi", insertLinebreaks("abc def ghi", 3));
        assertEquals("abc def\nghi", insertLinebreaks("abc def ghi", 4));
        assertEquals("abc def\nghi", insertLinebreaks("abc def ghi", 5));
        assertEquals("abc def\nghi", insertLinebreaks("abc def ghi", 6));
        assertEquals("abc def\nghi", insertLinebreaks("abc def ghi", 7));
        assertEquals("abc def ghi", insertLinebreaks("abc def ghi", 8));
    }

    public static String insertLinebreaks(String s, int charsPerLine) {
        char[] chars = s.toCharArray();
        int lastLinebreak = 0;
        boolean wantLinebreak = false;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            if (wantLinebreak && chars[i] == ' ') {
                sb.append('\n');
                lastLinebreak = i;
                wantLinebreak = false;
            } else {
                sb.append(chars[i]);
            }
            if (i - lastLinebreak + 1 == charsPerLine)
                wantLinebreak = true;
        }
        return sb.toString();
    }
}
3 голосов
/ 23 июня 2009

Лучшее решение: скопируйте строку в StringBuilder, чтобы вы могли вставлять / изменять символы без большого количества подстановок подстрок. Затем используйте метод indexOf (), который занимает начальную позицию, чтобы найти индекс для изменения.

Редактировать: код:

public static String breakString(String str, int size)
{
    StringBuilder work = new StringBuilder(str);
    int pos = 0;
    while ((pos = work.indexOf(" ", pos + size)) >= 0)
    {
        work.setCharAt(pos, '\n');
    }
    return work.toString();
}
1 голос
/ 23 июня 2009

Я бы перебрал строку вместо 30. Вы должны отслеживать 30, хотя.

psuedocode, потому что это звучит как домашнее задание:

charInLine=0
iterateOver each char in rawString
    if(charInLine++ > 30 && currChar==' ')
        charInLine=0
        currChar='\n'
0 голосов
/ 30 сентября 2018
    String s = "A very long string containing " +
"many many words and characters. " +
"Newlines will be entered at spaces.";
StringBuilder sb = new StringBuilder(s);
int i = 0;
while ((i = sb.indexOf(" ", i + 30)) != -1) {
    sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());

это правильный, я тоже попробовал это.

0 голосов
/ 23 июня 2009

Может быть, я что-то упустил. Что не так с

Строка s = ... s = s.substring (0, 30) + s.substring (30) .replace ('', '\ n');

Это заменяет все пробелы символами новой строки, начинающимися после символа 30.

Это немного менее эффективно, но для 200 символов это действительно не имеет значения (это очень мало для манипулирования данными).

Bruce

...