Exemplo n.º 1
0
        /*
         * Turn API to private - based on code review
         *
         * AddWordToTrieByOneCharATime
         * function is designed to complete the following tasks:
         * Add one word in the dictionary to Trie using recursive function
         * Add one char a time by scanning a word from left to right.
         *
         * Tricky part is to set prefix neighbor in the process.
         *
         * @index
         * @charArray
         * @word  -
         * @neighbor - prefix neighbor, it is empty string if there is no prefix neighbor
         *
         * function return:
         * Tuple<string, string> - string and its prefix neighbor
         */
        private Tuple <string, string> addWordToTrieByOneCharATime(
            int scanIndex,
            char[] charArray,
            string word,
            string neighbour)
        {
            bool isEndOfString = scanIndex == charArray.Length;

            if (isEndOfString)
            {
                IsWord         = true;
                PrefixNeighbor = word;

                return(new Tuple <string, string>(PrefixNeighbor, neighbour));
            }

            char visiting = charArray[scanIndex];

            if (!Children.ContainsKey(visiting))
            {
                Children[visiting] = new TrieWithPrefixNeighbor();
            }

            string updatedNeighbor = IsWord ? PrefixNeighbor : neighbour;

            // update neighbor string - if IsInDictionary is true, then it is
            // to set as a prefix neighbor
            return(Children[visiting].addWordToTrieByOneCharATime(
                       scanIndex + 1,
                       charArray,
                       word,
                       updatedNeighbor));
        }
Exemplo n.º 2
0
    /*
     * study LINQ - GroupBy
     * https://msdn.microsoft.com/en-us/library/bb534304(v=vs.110).aspx
     *
     * 1. Group string by first char, 26 variations from 'A', 'B', ..., 'Z'
     * 2. For each group, sort strings by string's length in ascending order
     * 3. For example, group of strings starting from char 'A',
     *    "A","AB","ACD"
     * 4. benefit value is to add all chars' ascii value.
     */
    static long Process(string[] dict)
    {
        var benefitValue = 0L;

        var groupped = dict.GroupBy(x => x[0]);

        // maximum 26 groups, 'A','B', ..., 'Z'
        foreach (var group in groupped)
        {
            // sort by string's length in ascending order
            var sortedStrings = group.OrderBy(x => x.Length);

            var trie   = new TrieWithPrefixNeighbor();
            var banned = new HashSet <string>();
            var stack  = new Stack <Tuple <string, string> >();

            foreach (var word in sortedStrings)
            {
                stack.Push(trie.AddWordToTrie(word, ""));
            }

            // Enumerate the stack, the longest string will be iterated first.
            // Maximum independent set is kind of greedy as well.
            foreach (var tuple in stack)
            {
                if (!banned.Contains(tuple.Item1))
                {
                    benefitValue += tuple.Item1.ToCharArray().Aggregate(0L, (val, next) => val + (long)next);
                    banned.Add(tuple.Item2);
                }
            }
        }

        return(benefitValue);
    }