fork(1) download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.*;
  4. import java.lang.*;
  5. import java.io.*;
  6.  
  7. enum TokenKind
  8. {
  9. WordSeparator,
  10. Word
  11. }
  12.  
  13. class Token
  14. {
  15. int _start;
  16. int _end;
  17. String _text;
  18. TokenKind _kind;
  19.  
  20. public String getText()
  21. {
  22. return _text;
  23. }
  24.  
  25. public void setText(String value)
  26. {
  27. _text = value;
  28. }
  29.  
  30. public void setStart(int value)
  31. {
  32. _start = value;
  33. }
  34.  
  35. public void setEnd(int value)
  36. {
  37. _end = value;
  38. }
  39.  
  40. public int getStart()
  41. {
  42. return _start;
  43. }
  44.  
  45. public int getEnd()
  46. {
  47. return _end;
  48. }
  49.  
  50. public TokenKind getKind()
  51. {
  52. return _kind;
  53. }
  54.  
  55. public void setKind(TokenKind value)
  56. {
  57. _kind = value;
  58. }
  59. }
  60.  
  61. class LinearRepeatSearchLexer
  62. {
  63. StringBuffer _text;
  64. int _position;
  65. char _peek;
  66.  
  67. public LinearRepeatSearchLexer(StringBuffer text)
  68. {
  69. _text = text;
  70. _position = 0;
  71. _peek = (char)0;
  72. }
  73.  
  74. public Token nextToken()
  75. {
  76. Token ret = new Token();
  77. char peek = PeekChar();
  78.  
  79. if(isWordSeparator(peek))
  80. {
  81. ret.setStart(_position);
  82. readWordSeparator(ret);
  83. ret.setEnd(_position - 1);
  84. return ret;
  85. }
  86. else if(isLetterOrDigit(peek))
  87. {
  88. ret.setStart(_position);
  89. readWord(ret);
  90. ret.setEnd(_position - 1);
  91. return ret;
  92. }
  93. else if(peek == (char)0)
  94. {
  95. return null;
  96. }
  97. else
  98. {
  99. // TODO:
  100. // caracteres não identificados
  101. // ou você pode simplificar o readWord
  102. return null;
  103. }
  104. }
  105.  
  106. void readWordSeparator(Token token)
  107. {
  108. char c = (char)0;
  109. StringBuffer tokenText = new StringBuffer();
  110. while(isWordSeparator(c = PeekChar()))
  111. {
  112. tokenText.append(c);
  113. MoveNext(1);
  114. }
  115. token.setText(tokenText.toString());
  116. token.setKind(TokenKind.WordSeparator);
  117. }
  118.  
  119. void readWord(Token token)
  120. {
  121. char c = (char)0;
  122. StringBuffer tokenText = new StringBuffer();
  123. while(isLetterOrDigit(c = PeekChar()))
  124. {
  125. tokenText.append(c);
  126. MoveNext(1);
  127. }
  128. token.setText(tokenText.toString());
  129. token.setKind(TokenKind.Word);
  130. }
  131.  
  132. boolean isWordSeparator(char c)
  133. {
  134. // TODO: outros separadores aqui
  135. return c == ' ' ||
  136. c == '\t' ||
  137. c == '\n' ||
  138. c == '\r' ||
  139. c == ',' ||
  140. c == '.' ||
  141. c == '-' ||
  142. c == ';' ||
  143. c == ':' ||
  144. c == '=' ||
  145. c == '>';
  146. }
  147.  
  148. boolean isLetterOrDigit(char c)
  149. {
  150. // TODO: outras letras aqui
  151. return (c >= 'a' && c <= 'z') ||
  152. (c >= 'A' && c <= 'Z') ||
  153. (c >= '0' && c <= '9') ||
  154. (c >= 'à' && c <= 'ú') ||
  155. (c >= 'À' && c <= 'Ú') ||
  156. c == '_';
  157. }
  158.  
  159. char PeekChar()
  160. {
  161. if(_position < _text.length())
  162. return _text.charAt(_position);
  163. return (char)0;
  164. }
  165.  
  166. void MoveNext(int plus)
  167. {
  168. _position += plus;
  169. }
  170. }
  171.  
  172. class LinearRepeatSearch
  173. {
  174. StringBuffer _text;
  175. int _radius;
  176.  
  177. public LinearRepeatSearch(StringBuffer text, int radius)
  178. {
  179. _text = text;
  180. _radius = radius;
  181. }
  182.  
  183. public LinearRepeatSearch(String text, int radius)
  184. {
  185. this(new StringBuffer(text), radius);
  186. }
  187.  
  188. public List<Token> getRepeatedWords()
  189. {
  190. // ler todos os tokens
  191. ArrayList<Token> ret = new ArrayList<Token>();
  192. ArrayList<Token> readed = new ArrayList<Token>();
  193. LinearRepeatSearchLexer lexer = new LinearRepeatSearchLexer(_text);
  194. Token token = null;
  195. while((token = lexer.nextToken()) != null)
  196. {
  197. if(token.getKind() == TokenKind.Word)
  198. readed.add(token);
  199. }
  200.  
  201. // localizar repetições a partir do raio
  202. // PERF:
  203. // este laço pode ser melhorado em termos de performance
  204. // pois há comparações repetidas aqui
  205. int size = readed.size();
  206. for(int x = 0; x < size; x++)
  207. {
  208. Token a = readed.get(x);
  209. for(int y = Math.max(0, x - _radius); y < size && (y - x) < _radius; y++)
  210. {
  211. if(x == y) continue;
  212. Token b = readed.get(y);
  213. if(a.getText().equals(b.getText()))
  214. {
  215. ret.add(a);
  216. break;
  217. }
  218. }
  219. }
  220.  
  221. return ret;
  222. }
  223. }
  224.  
  225. class Ideone
  226. {
  227. public static void main (String[] args) throws java.lang.Exception
  228. {
  229. // your code goes here
  230.  
  231. StringBuffer input = new StringBuffer("Hoje em dia, é necessário ser esperto. O nosso dia a dia é complicado.");
  232. StringBuffer output = new StringBuffer();
  233. LinearRepeatSearch searcher = new LinearRepeatSearch(input, 10);
  234. List<Token> spans = searcher.getRepeatedWords();
  235. int listSize = spans.size();
  236. int position = 0;
  237. for(int x = 0; x < listSize; x++)
  238. {
  239. Token item = spans.get(x);
  240. output.append(input.substring(position, item.getStart()));
  241. output.append("<b>");
  242. output.append(item.getText());
  243. output.append("</b>");
  244. position = item.getEnd() + 1;
  245. }
  246. if(position < input.length())
  247. {
  248. output.append(input.substring(position));
  249. }
  250. System.out.println(output.toString());
  251. }
  252. }
Success #stdin #stdout 0.1s 320320KB
stdin
Standard input is empty
stdout
Hoje em <b>dia</b>, <b>é</b> necessário ser esperto. O nosso <b>dia</b> a <b>dia</b> <b>é</b> complicado.