コード例 #1
0
ファイル: Analyzer.cs プロジェクト: MarkAHamann/MorseTrainer
        public void Analyze(String sent, String recorded)
        {
            _resultsRTB.Clear();
            MorseCompareResults results = Comparer.Compare(sent, recorded);

            ShowStrings(results);
            ShowStats(results);
            _resultsRTB.Select(0, 0);
            _resultsRTB.ScrollToCaret();
        }
コード例 #2
0
ファイル: Analyzer.cs プロジェクト: MarkAHamann/MorseTrainer
        private void ShowStrings(MorseCompareResults results)
        {
            Write("I sent   : ");
            ResultsFlags flags = ResultsFlags.Valid | ResultsFlags.Dropped;

            foreach (MorseSubstring substring in results.SubStrings)
            {
                Write(substring.Str(flags), substring.Color);
            }
            Write(Environment.NewLine);

            Write("You typed: ");
            flags = ResultsFlags.Valid | ResultsFlags.Extra;
            foreach (MorseSubstring substring in results.SubStrings)
            {
                Write(substring.Str(flags), substring.Color);
            }
            Write(Environment.NewLine);
        }
コード例 #3
0
        /// <summary>
        /// Compares two strings and returns the results.
        /// </summary>
        /// <param name="sent">The sent string</param>
        /// <param name="recorded">The string the user entered while listening</param>
        /// <returns>Am objecxt with results</returns>
        public static MorseCompareResults Compare(string sent, string recorded)
        {
            const int SEARCH_AMOUNT = 20;

            int sentStart      = 0;
            int recordedStart  = 0;
            int sentLength     = sent.Length;
            int recordedLength = recorded.Length;
            int sum            = 0;
            int sentOffset     = 0;
            int recordedOffset = 0;
            int matched        = 0;
            int threshold;
            int matchedTotal = 0;

            List <MorseSubstring> substringList = new List <MorseSubstring>();

            // As long as there are unprocessed characters
            while (sentStart < sentLength || recordedStart < recordedLength)
            {
                bool searching         = true;
                int  sentRemaining     = sentLength - sentStart;
                int  recordedRemaining = recordedLength - recordedStart;
                int  maxSum            = sentRemaining + recordedRemaining;

                // start with a higher threshold to filter false positives, then loosen
                for (int thresholdIndex = 0; searching && (thresholdIndex < matchLengthThresholdArray.Length); ++thresholdIndex)
                {
                    // a match is considered a match if it is contains at least 'threshold' contiguous matching characters
                    threshold = matchLengthThresholdArray[thresholdIndex];
                    int searchAmount = Math.Min(SEARCH_AMOUNT, maxSum);

                    // The algorithm here is to match positive offsets on each string
                    // starting from (0,0) (0,1) (1,0) (0,2) (1,1) (2,0) (0,3) (1,2) (2,1) (3,0) (0,4) ...
                    // until (0,searchAmount) ... (searchAmount,0)
                    for (sum = 0; searching && (sum < searchAmount); ++sum)
                    {
                        for (sentOffset = 0; sentOffset <= sum; ++sentOffset)
                        {
                            // get the respective offsets from the start
                            recordedOffset = sum - sentOffset;

                            // number of matching characters starting at the respective offsets
                            matched = matchCount(sent, recorded, sentStart + sentOffset, recordedStart + recordedOffset);

                            // got matched, leave sentOffset for loop
                            if (matched >= threshold)
                            {
                                // found!
                                searching = false;
                                break;
                            }
                        }
                    }
                }

                // At this point we have matched and the offsets
                if (searching)
                {
                    // didn't find a match--punt and just put everything into the mismatch output
                    sentOffset     = sentLength - sentStart;
                    recordedOffset = recordedLength - recordedStart;
                }

                // sum > 0 means that there was either extra or dropped characters detected before a substring match
                if (sum > 0)
                {
                    if (sentOffset > 0)
                    {
                        // at least one character was dropped
                        MorseSubstring dropped = new MorseDropped(sent.Substring(sentStart, sentOffset));
                        substringList.Add(dropped);

                        // skip over the dropped characters to the start of the match
                        sentStart += sentOffset;
                    }
                    if (recordedOffset > 0)
                    {
                        // at least one unsent character was detected before a substring match
                        MorseSubstring extra = new MorseExtra(recorded.Substring(recordedStart, recordedOffset));
                        substringList.Add(extra);

                        // skip over the extra characters to the start of the match
                        recordedStart += recordedOffset;
                    }
                }
                if (matched > 0)
                {
                    // there was a match
                    MorseSubstring valid = new MorseValid(sent.Substring(sentStart, matched));
                    substringList.Add(valid);

                    // skip over the match in each string
                    recordedStart += matched;
                    sentStart     += matched;

                    // keep track of the matched total
                    matchedTotal += matched;
                }
            }

            MorseCompareResults results = new MorseCompareResults(substringList, sent, recorded);

            return(results);
        }
コード例 #4
0
ファイル: Analyzer.cs プロジェクト: MarkAHamann/MorseTrainer
        private void ShowStats(MorseCompareResults results)
        {
            int[] sent       = new int[256];
            int[] valid      = new int[256];
            int[] dropped    = new int[256];
            int[] extra      = new int[256];
            int   totalValid = 0;

            foreach (char c in results.Sent)
            {
                sent[c]++;
            }
            foreach (MorseSubstring substring in results.SubStrings)
            {
                int[] counter = null;
                switch (substring.ResultInfo & ResultsFlags.All)
                {
                case ResultsFlags.Dropped:
                    counter = dropped;
                    break;

                case ResultsFlags.Extra:
                    counter = extra;
                    break;

                case ResultsFlags.Valid:
                    counter     = valid;
                    totalValid += substring.Chars.Length;
                    break;
                }
                if (counter != null)
                {
                    foreach (char c in substring.Chars)
                    {
                        counter[c]++;
                    }
                }
            }

            Write(String.Format("Sent {0} and {1} recorded valid: {2:0}%" + Environment.NewLine, results.Sent.Length, totalValid, 100 * (float)totalValid / (float)results.Sent.Length));

            // Show characters sent
            Write(Environment.NewLine + "Characters sent:" + Environment.NewLine);
            foreach (char c in MorseInfo.PossibleCharacters)
            {
                if (sent[c] != 0)
                {
                    Write(String.Format(" {0} {1}/{2} : {3},{4}" + Environment.NewLine, MorseInfo.ExpandProsigns(c), valid[c], sent[c], dropped[c], extra[c]));
                }
            }

            // Show extra characters received
            Write(Environment.NewLine + "Characters not sent:" + Environment.NewLine);
            foreach (char c in MorseInfo.PossibleCharacters)
            {
                if (sent[c] == 0 && extra[c] != 0)
                {
                    Write(String.Format(" {0} {1}/{2} : {3},{4}" + Environment.NewLine, MorseInfo.ExpandProsigns(c), valid[c], sent[c], dropped[c], extra[c]));
                }
            }
        }