Moderate 加入空格使得可辨别单词数量最多 @CareerCup

递归题目,注意结合了memo的方法和trie的应用

 

 

[java][/java]

  1. package Moderate;
  2. import java.util.Hashtable;
  3. import CtCILibrary.AssortedMethods;
  4. import CtCILibrary.Trie;
  5. /**
  6.  *  Oh, no! You have just completed  a lengthy  document when you have an  unfortu-
  7. nate Find/Replace mishap.  You have accidentally  removed all spaces, punctuation,
  8. and  capitalization  in  the document. A sentence like  “I reset  the  computer.  It  still
  9. didn’t boot!” would become “iresetthecomputeritstilldidntboot”.  You figure that you
  10. can add back in the punctation and capitalization later, once you get the individual
  11. words properly separated. Most of the words will be in a dictionary,  but some strings,
  12. like proper names, will  not.
  13. Given a dictionary  (a list of words), design an algorithm  to find the optimal way of
  14. “unconcatenating” a sequence of words. In this case, “optimal” is defined  to be the
  15. parsing  which  minimizes  the number  of unrecognized sequences of characters.
  16. For example, the string “jesslookedjustliketimherbrother”  would be optimally parsed
  17. as  “JESS looked just like TIM her brother”. This parsing  has seven unrecognized  char-
  18. acters, which  we have capitalized  for  clarity.
  19. 给一个string,把string内的所有标点,空格都去掉。然后要求找到把空格加回去使得不可辨别的
  20. 单词数量达到最少的方法(判断是否可以辨别是通过提供一个字典来判断)
  21.  *
  22.  */
  23. public class S17_14 {
  24.     public static String sentence;
  25.     public static Trie dictionary;
  26.     /* incomplete code */
  27.     public static Result parse(int wordStart, int wordEnd, Hashtable<Integer, Result> cache) {
  28.             if (wordEnd >= sentence.length()) {
  29.                     return new Result(wordEnd – wordStart, sentence.substring(wordStart).toUpperCase());
  30.             }
  31.             if (cache.containsKey(wordStart)) {
  32.                     return cache.get(wordStart).clone();
  33.             }
  34.             String currentWord = sentence.substring(wordStart, wordEnd + 1);
  35.             boolean validPartial = dictionary.contains(currentWord, false);
  36.             boolean validExact = validPartial && dictionary.contains(currentWord, true);
  37.             /* break current word */
  38.             Result bestExact = parse(wordEnd + 1, wordEnd + 1, cache);
  39.             if (validExact) {
  40.                     bestExact.parsed = currentWord + ” ” + bestExact.parsed;
  41.             } else {
  42.                     bestExact.invalid += currentWord.length();
  43.                     bestExact.parsed = currentWord.toUpperCase() + ” ” + bestExact.parsed;
  44.             }
  45.             /* extend current word */
  46.             Result bestExtend = null;
  47.             if (validPartial) {
  48.                     bestExtend = parse(wordStart, wordEnd + 1, cache);
  49.             }
  50.             /* find best */
  51.             Result best = Result.min(bestExact, bestExtend);
  52.             cache.put(wordStart, best.clone());
  53.             return best;
  54.     }
  55.     public static int parseOptimized(int wordStart, int wordEnd, Hashtable<Integer, Integer> cache) {
  56.             if (wordEnd >= sentence.length()) {
  57.                     return wordEnd – wordStart;
  58.             }
  59.             if (cache.containsKey(wordStart)) {
  60.                     return cache.get(wordStart);
  61.             }
  62.             String currentWord = sentence.substring(wordStart, wordEnd + 1);
  63.             boolean validPartial = dictionary.contains(currentWord, false);
  64.             /* break current word */
  65.             int bestExact = parseOptimized(wordEnd + 1, wordEnd + 1, cache);
  66.             if (!validPartial || !dictionary.contains(currentWord, true)) {
  67.                     bestExact += currentWord.length();
  68.             }
  69.             /* extend current word */
  70.             int bestExtend = Integer.MAX_VALUE;
  71.             if (validPartial) {
  72.                     bestExtend = parseOptimized(wordStart, wordEnd + 1, cache);
  73.             }
  74.             /* find best */
  75.             int min = Math.min(bestExact, bestExtend);
  76.             cache.put(wordStart, min);
  77.             return min;
  78.     }
  79.     public static int parseSimple(int wordStart, int wordEnd) {
  80.             if (wordEnd >= sentence.length()) {
  81.                     return wordEnd – wordStart;
  82.             }
  83.             String word = sentence.substring(wordStart, wordEnd + 1);
  84.             /* break current word */
  85.             int bestExact = parseSimple(wordEnd + 1, wordEnd + 1);
  86.             if (!dictionary.contains(word, true)) {
  87.                     bestExact += word.length();
  88.             }
  89.             /* extend current word */
  90.             int bestExtend = parseSimple(wordStart, wordEnd + 1);
  91.             /* find best */
  92.             return Math.min(bestExact, bestExtend);
  93.     }
  94.     public static String clean(String str) {
  95.             char[] punctuation = {‘,’, ‘”‘, ‘!’, ‘.’, ‘\”, ‘?’, ‘,’};
  96.             for (char c : punctuation) {
  97.                     str = str.replace(c, ‘ ‘);
  98.             }
  99.             return str.replace(” “, “”).toLowerCase();
  100.     }
  101.     public static void main(String[] args) {
  102.             dictionary = AssortedMethods.getTrieDictionary();
  103.             sentence = “As one of the top companies in the world, Google will surely attract the attention of computer gurus. This does not, however, mean the company is for everyone.”;
  104.             sentence = clean(sentence);
  105.             System.out.println(sentence);
  106.             //Result v = parse(0, 0, new Hashtable<Integer, Result>());
  107.             //System.out.println(v.parsed);
  108.             int v = parseOptimized(0, 0, new Hashtable<Integer, Integer>());
  109.             System.out.println(v);
  110.     }
  111.     static class Result {
  112.         public int invalid = Integer.MAX_VALUE;
  113.         public String parsed = “”;
  114.         public Result(int inv, String p) {
  115.                 invalid = inv;
  116.                 parsed = p;
  117.         }
  118.         public Result clone() {
  119.                 return new Result(this.invalid, this.parsed);
  120.         }
  121.         public static Result min(Result r1, Result r2) {
  122.                 if (r1 == null) {
  123.                         return r2;
  124.                 } else if (r2 == null) {
  125.                         return r1;
  126.                 }
  127.                 return r2.invalid < r1.invalid ? r2 : r1;
  128.         }
  129.     }
  130. }

标签