private string BestStringSplit(Hashtable ht, string sentence)
        {
            //We can use ht as memo or array of ParseResult object
            Dictionary <int, ParseResult1> memo = new Dictionary <int, ParseResult1>();
            ParseResult1 r = Split(ht, sentence, 0, memo);

            return(r == null ? null : r.Parsed);
        }
        private ParseResult1 Split(Hashtable ht, string sentence, int index, Dictionary <int, ParseResult1> memo)
        {
            if (index >= sentence.Length)
            {
                return(new ParseResult1(0, string.Empty));
            }

            if (memo.ContainsKey(index))
            {
                return(memo[index]);
            }
            int    bestInvalid = Int32.MaxValue;
            string bestparsing = null;
            string partial     = "";
            int    startindex  = index;

            while (startindex < sentence.Length)
            {
                char c = sentence[startindex];
                partial += c;
                int invalid = ht.ContainsKey(partial) ? 0 : partial.Length;
                if (invalid < bestInvalid)
                {
                    ParseResult1 result = Split(ht, sentence, startindex + 1, memo);

                    if (invalid + result.NoOfInvalidCharacters < bestInvalid)
                    {
                        bestInvalid = invalid + result.NoOfInvalidCharacters;

                        bestparsing = partial + " " + result.Parsed;

                        if (bestInvalid == 0)
                        {
                            break;
                        }
                    }
                }

                //This is important step..increment the index to see every possible prefix starting from this index can make best split
                startindex++;
            }

            ParseResult1 indexbestparse = new ParseResult1(bestInvalid, bestparsing);

            memo.Add(index, indexbestparse);
            return(indexbestparse);
        }