Advertisement
T99

StringTokenizer.java

T99
Jun 29th, 2018
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.06 KB | None | 0 0
  1. // ATTEMPT #1
  2.  
  3. public static String[] tokenize(String input) {
  4.  
  5.     input = input.trim();
  6.  
  7.     if (input.isEmpty()) return new String[0];
  8.  
  9.     TreeMap<Integer, String> tokenizedInputMap = new TreeMap<>();
  10.  
  11.     char activeDelimiter = ' ';
  12.     boolean isSearchingForClosingDelimiter = false;
  13.     int openingDelimiterIndex = 0;
  14.  
  15.     for (int i = 0; i < input.length(); i++) {
  16.  
  17.         char currentChar = input.substring(i, i + 1).charAt(0);
  18.  
  19.         if (isSearchingForClosingDelimiter) {
  20.  
  21.             int indexOfClosingDelimiter = input.indexOf(String.valueOf(activeDelimiter), openingDelimiterIndex + 1);
  22.  
  23.             if (indexOfClosingDelimiter != -1) {
  24.  
  25.                 tokenizedInputMap.put(openingDelimiterIndex, input.substring(openingDelimiterIndex + 1, indexOfClosingDelimiter));
  26.                 i = indexOfClosingDelimiter + 1;
  27.  
  28.             } else {
  29.  
  30.                 // unclosed string group
  31.  
  32.             }
  33.  
  34.         } else {
  35.  
  36.             if (validDelimiters.contains(currentChar)) {
  37.  
  38.                 activeDelimiter = currentChar;
  39.                 isSearchingForClosingDelimiter = true;
  40.                 openingDelimiterIndex = i;
  41.  
  42.             } else if (currentChar == ' ') {
  43.  
  44.                 tokenizedInputMap.put(openingDelimiterIndex, input.substring(openingDelimiterIndex, i));
  45.                 openingDelimiterIndex = i + 1;
  46.  
  47.             } else if (i == input.length() - 1) {
  48.  
  49.                 tokenizedInputMap.put(openingDelimiterIndex, input.substring(openingDelimiterIndex, i + 1));
  50.  
  51.             }
  52.  
  53.         }
  54.  
  55.     }
  56.  
  57.     return tokenizedInputMap.values().toArray(new String[0]);
  58.  
  59. }
  60.  
  61. //==================================================================================================================
  62. // ATTEMPT #2
  63.  
  64. public static String[] tokenize(String input) throws UnclosedDelimiterException {
  65.    
  66.     input = input.trim();
  67.    
  68.     if (input.isEmpty()) return new String[0];
  69.    
  70.     TreeMap<Integer, String> tokenizedInputMap = new TreeMap<>();
  71.    
  72.     int index = 0;
  73.     CharacterOccurrence openingCO = new CharacterOccurrence(0, input.charAt(0));
  74.     CharacterOccurrence closingCO = new CharacterOccurrence(0, input.charAt(0));
  75.     TokenizerMode mode = TokenizerMode.getModeForCharacter(openingCO.getCharacter());
  76.     if (mode == null) mode = TokenizerMode.SPACE_DELIMITING;
  77.    
  78.     interpreterLoop:
  79.     while (index < input.length()) {
  80.        
  81.         switchBlock:
  82.         switch (mode) {
  83.            
  84.             case SPACE_DELIMITING: {
  85.                
  86.                 closingCO = checkForNextOccurrenceOf(input, index, mode.getValidDelimiters());
  87.                
  88.                 if (closingCO != null) {
  89.                    
  90.                     tokenizedInputMap.put(openingCO.getIndex(), input.substring(openingCO.getIndex(), closingCO.getIndex()));
  91.                     break switchBlock;
  92.                    
  93.                 } else {
  94.                    
  95.                     tokenizedInputMap.put(openingCO.getIndex(), input.substring(openingCO.getIndex(), input.length()));
  96.                     break interpreterLoop;
  97.                
  98.                 }
  99.            
  100.             }
  101.            
  102.             case QUOTE_DELIMITING: {
  103.                
  104.                 closingCO = checkForNextOccurrenceOf(input, index + 1, openingCO.getCharacter());
  105.                
  106.                 if (closingCO == null) throw new UnclosedDelimiterException(openingCO.getCharacter());
  107.                 else tokenizedInputMap.put(openingCO.getIndex(), input.substring(openingCO.getIndex() + 1, closingCO.getIndex()));
  108.                
  109.                 break switchBlock;
  110.            
  111.             }
  112.            
  113.         }
  114.        
  115.         if (input.length() >= closingCO.getIndex() + 1) index = closingCO.getIndex() + 1;
  116.         else break interpreterLoop;
  117.        
  118.         CharacterOccurrence currentCO;
  119.         CharacterOccurrence precedingCO = new CharacterOccurrence(index - 1, input.charAt(index - 1));
  120.        
  121.         while (input.length() > index) {
  122.            
  123.             currentCO = new CharacterOccurrence(index, input.charAt(index));
  124.            
  125.             if (TokenizerMode.getModeForCharacter(currentCO.getCharacter()) == null) { // The currentCO is not a valid delimiter...
  126.                
  127.                 openingCO = currentCO;
  128.                 mode = TokenizerMode.getModeForCharacter(openingCO.getCharacter());
  129.                 if (mode == null) mode = TokenizerMode.SPACE_DELIMITING;
  130.                 continue interpreterLoop;
  131.                
  132.             } else { // The current character is a valid delimiter...
  133.            
  134.                 precedingCO = currentCO;
  135.                 index++;
  136.            
  137.             }
  138.            
  139.         }
  140.        
  141.         break interpreterLoop;
  142.        
  143.     }
  144.    
  145.     return tokenizedInputMap.values().toArray(new String[0]);
  146.    
  147. }
  148.  
  149. public static CharacterOccurrence checkForNextOccurrenceOf(String searchIn, int searchFrom, char... searchChars) {
  150.    
  151.     TreeMap<Integer, Character> occurrences = new TreeMap<>();
  152.    
  153.     for (char searchChar: searchChars) {
  154.        
  155.         int indexOfResult = searchIn.indexOf(String.valueOf(searchChar), searchFrom);
  156.         if (indexOfResult != -1) occurrences.put(indexOfResult, searchChar);
  157.        
  158.     }
  159.    
  160.     Map.Entry<Integer, Character> firstResult = occurrences.firstEntry();
  161.    
  162.     if (firstResult == null) return null;
  163.     else return new CharacterOccurrence(firstResult.getKey(), firstResult.getValue());
  164.    
  165. }
  166.  
  167. private static class CharacterOccurrence {
  168.    
  169.     int index;
  170.     char character;
  171.    
  172.     CharacterOccurrence(int index, char character) {
  173.        
  174.         this.index = index;
  175.         this.character = character;
  176.        
  177.     }
  178.    
  179.     int getIndex() {
  180.        
  181.         return index;
  182.        
  183.     }
  184.    
  185.     char getCharacter() {
  186.        
  187.         return character;
  188.        
  189.     }
  190.    
  191. }
  192.  
  193. private enum TokenizerMode {
  194.    
  195.     SPACE_DELIMITING (' '),
  196.     QUOTE_DELIMITING ('\'', '"', '`');
  197.    
  198.     final char[] validDelimiters;
  199.     static Map<Character, TokenizerMode> reverseLookup = new HashMap<>();
  200.     static char[] allValidDelimiters;
  201.    
  202.     static {
  203.        
  204.         for (TokenizerMode mode: values()) {
  205.            
  206.             for (char c: mode.getValidDelimiters()) {
  207.                
  208.                 reverseLookup.put(c, mode);
  209.                
  210.             }
  211.            
  212.         }
  213.        
  214.     }
  215.    
  216.     TokenizerMode(char... validDelimiters) {
  217.        
  218.         this.validDelimiters = validDelimiters;
  219.        
  220.     }
  221.    
  222.     static char[] getAllValidDelimiters() {
  223.        
  224.         if (allValidDelimiters == null) {
  225.            
  226.             allValidDelimiters = new char[reverseLookup.keySet().size()];
  227.            
  228.             for (int i = 0; i < allValidDelimiters.length; i++) {
  229.                
  230.                 allValidDelimiters[i] = reverseLookup.keySet().toArray(new Character[0])[i];
  231.                
  232.             }
  233.            
  234.         }
  235.        
  236.         return allValidDelimiters;
  237.        
  238.     }
  239.    
  240.     boolean checkIfValidDelimiter(char character) {
  241.    
  242.         for (char c: validDelimiters) {
  243.            
  244.             if (c == character) return true;
  245.            
  246.         }
  247.        
  248.         return false;
  249.    
  250.     }
  251.    
  252.     char[] getValidDelimiters() {
  253.        
  254.         return validDelimiters;
  255.        
  256.     }
  257.    
  258.     static TokenizerMode getModeForCharacter(char character) {
  259.        
  260.         return reverseLookup.get(character);
  261.        
  262.     }
  263.    
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement