2015-02-09 4 views
1

У меня есть Set из character разделителей (DELIMITERS), например ., и т.д. С помощью этого я хочу, чтобы разделить текст и получить слова с их позицией в тексте. String.split() работает нормально, если вы хотите только слова. То же самое с StringTokenizer. Написал какой-то простой способ справиться с этим, но, может быть, есть лучший способ достичь этого результата?Текста токенизатора - извлечение слова и позиция из текста

public List<String> extractWords(String text){ 
    List<String> words = new ArrayList<>(); 
    List<WordPos> positions = new ArrayList<>(); 
    int wordStart = -1; 
    for(int i=0; i < text.length(); i++){ 
     if(DELIMITERS.contains(text.charAt(i))){ 
      if(wordStart >=0){ //word just ended 
       String word = text.substring(wordStart, i); 
       positions.add(new WordPos(wordStart, i)); 
       words.add(word); 
      } 
      wordStart = -1; 
     }else{ //not delimiter == valid word 
      if(wordStart < 0){ //word just started 
       wordStart = i; 
      } 
     } 
    } 
    return words; 
} 

// inner static class for words positions 
public static class WordPos{ 
    int start; 
    int end; 
    public WordPos(int start, int end){ 
     this.start = start; 
     this.end = end; 
    } 
} 
+4

Я думаю, вы должны опубликовать это на http://codereview.stackexchange.com/ – Matt

ответ

0

С точки зрения эффективности, я думаю, что ваше решение неплохое. С эстетического аспектом (как выглядит код), я хотел бы использовать Apache Commons nStringUtils делать что-то вроде (не пробовали):

  1. вертел все жетоны с помощью: splitPreserveAllTokens()
  2. итерации через полученный массив и хранить маркер и положение каждого из них, которое я получил бы от вызова lastIndexOf.
+4

Но вызов 'lastIndexOf' каждый раз может замедлить цикл ... –

+0

@silvaran, разве вы не прочитали первое предложение мой ответ? Я не говорил, что это умение работать лучше всего ... однако, производительность явно не упоминалась как цель. Я думаю, что с точки зрения «чистого кода» лучше иметь его как тонким, так и читаемым. – aviad

0
List<String> words = new ArrayList<>(); 
List<WordPos> positions = new ArrayList<>(); 
int index = 0; 
String word = ""; 
StringTokenizer st = new StringTokenizer("., "); 


while(st.hasMoreTokens()) { 

word = st.nextToken(); 
words.add(word); 
positions.add(new WordPos(index,index+word.length())); 

index+= word.length() +1; 
} 

С вышеизложенным подходом я полагаю там не 2 последовательных разделителей. Если это произойдет, то подход будет совершенно таким же.

+4

Но могут быть два разделителя. «Джон пошел домой, небо голубое». Точка и пространство вместе. – bartektartanus

+0

@bartektartanus Есть ли фиксированный набор разделителей или он может измениться? –

Смежные вопросы