Hmmm, this application has changed a bit since my original contribution. Having to figure out exactly what it is supposed to do is the majority of the work I would say. I have been stepping through CompareString and CompareWord methods, and I believe I have been misunderstanding what you are doing all along.

First, let me say your search code is very interesting. However, your program has little or no embedded comments explaining how the FormSearcher class is supposed to work, so I need you to verify my understanding before I continue further because I don't want to waste any more time proceeding down a falsely assumed path...

As I understand it, and you need to make sure I haven't missed anything, this is how you are determining whether the given string is enough of a match to constitute the form item being displayed:

Regarding user supplied string:
1) words to compare are whitespace delimited and must be at least 2 chars in length
1a) correction (see SPLIT comment below) : there is always only one word with whitespace removed!!!

For each word (loop) against the complete form's string:
2) each word is compared to the form's string by finding the location in the form's string where the 1st character of the word is found
3) you then remove that character from the form's string and beginning again with the 2nd character of the word
4) each found word character gets a match count increment
5) thus, you are counting the first instance of each character from the word found in the form's string
6) then, determining what percent of the word based on the percentage of the word's length the form's string length is a match; if that percent is >= 75%, you count that as a matched word

OK, I've been editing this and testing as I go along and as far as I can figure, the "word" is all of the text entered by the user because you have told it to ignore whitespace when splitting the text into an array, so the array has only one item or word... So, I gather you are using that to remove spaces and when you compare length < 2 that is for the entire string length because there always only one word the way I see it... So you are not really matching words at all, but a percent of characters existing in the string in any order? CONFIRM, CONFIRM, CONFIRM...

Anyway, here are some of the results I got and you should confirm these are expected:

Therefore, if user enters "69 ^ 2 E v 2 /a l u + 8 / a t e 3 + 5 / 2 ( 6 \ 9 + 6 ) .", this will match Form3 ("Evaluate2/3+5/6+8/9^22(6\9+6)."), which has a picture of a suitcase or something. Is that how it is supposed to work?
s
Also matches:
"Evaluate23568922696/+/+/^"

Also, you have a backslash in: "Evaluate2/3+5/6+8/9^22(6\9+6)." Is that intended?

Hmmm, this application has changed a bit since my original contribution. Having to figure out exactly what it is supposed to do is the majority of the work I would say. I have been stepping through CompareString and CompareWord methods, and I believe I have been misunderstanding what you are doing all along.

First, let me say your search code is very interesting. However, your program has little or no embedded comments explaining how the FormSearcher class is supposed to work, so I need you to verify my understanding before I continue further because I don't want to waste any more time proceeding down a falsely assumed path...

As I understand it, and you need to make sure I haven't missed anything, this is how you are determining whether the given string is enough of a match to constitute the form item being displayed:

Regarding user supplied string:
1) words to compare are whitespace delimited and must be at least 2 chars in length
1a) correction (see SPLIT comment below) : there is always only one word with whitespace removed!!!

For each word (loop) against the complete form's string:
2) each word is compared to the form's string by finding the location in the form's string where the 1st character of the word is found
3) you then remove that character from the form's string and beginning again with the 2nd character of the word
4) each found word character gets a match count increment
5) thus, you are counting the first instance of each character from the word found in the form's string
6) then, determining what percent of the word based on the percentage of the word's length the form's string length is a match; if that percent is >= 75%, you count that as a matched word

OK, I've been editing this and testing as I go along and as far as I can figure, the "word" is all of the text entered by the user because you have told it to ignore whitespace when splitting the text into an array, so the array has only one item or word... So, I gather you are using that to remove spaces and when you compare length < 2 that is for the entire string length because there always only one word the way I see it... So you are not really matching words at all, but a percent of characters existing in the string in any order? CONFIRM, CONFIRM, CONFIRM...

Anyway, here are some of the results I got and you should confirm these are expected:

Therefore, if user enters "69 ^ 2 E v 2 /a l u + 8 / a t e 3 + 5 / 2 ( 6 \ 9 + 6 ) .", this will match Form3 ("Evaluate2/3+5/6+8/9^22(6\9+6)."), which has a picture of a suitcase or something. Is that how it is supposed to work?
s
Also matches:
"Evaluate23568922696/+/+/^"

Also, you have a backslash in: "Evaluate2/3+5/6+8/9^22(6\9+6)." Is that intended?

yes, CONFIRM, CONFIRM, CONFIRM................
Yes i want to match in the same way as you mentioned in above examples..............
i want that there can be any character in the string , but if they matches 75% or more(Given percentage in code) with the form text characters, it should display the result.

Here are the changes you requested. I did not modify the code that determines the actual pct of matching because you indicated that was how you wanted it to work--so don't ask me to change that portion of your code because I want to clear this off my desk so-to-speak...

In the code that follows, you will find my changes easily, because it is practically the only code that has comments! What I did was store the SearchResults meeting your existing pct match routines (with the exception of modifying the return value of CompareString method), sort the pct match, then added them to your results in descending order (highest pct match first). I hope this solves your problem.

public SearchResult[] FindString(string Text)
    {
        // SearchResults keyed by matched pct...
        Dictionary<decimal, SearchResult> dictResults = new Dictionary<decimal, SearchResult>();
        // Create a list of match pct keys, sort...
        List<decimal> sortedKeys = new List<decimal>();

        List<SearchResult> result = new List<SearchResult>();

        foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
        {
            if (type.IsSubclassOf(typeof(Form)))
            {
                if (this.ExcludeTypes.Contains(type))
                    continue;

                using (Form f = (Form)Activator.CreateInstance(type))
                {
                    // Now returns mathced pct instead of bool...
                    decimal matchPct = CompareString(Text, f.Text);
                    
                    //if (CompareString(Text, f.Text))

                    // Only add if matched pct made minimum criteria...
                    if (matchPct > 0.0M)
                    {
                        SearchResult sr = new SearchResult(type, f.Text);
                        sr.Images.AddRange(FindImage(f));
                    
                        // Add new SearchResult to our keyed matches...
                        dictResults.Add(matchPct, sr);
                        // Add key to our sort list...
                        sortedKeys.Add(matchPct);
                    }
                }
            }
        }

        // sort the list of keys for sorted lookup...
        sortedKeys.Sort();

        // Add each SearchResult in order of highest pct match first (descending)...
        for (int i = sortedKeys.Count - 1; i >= 0; i--)
        {
            result.Add(dictResults[sortedKeys[i]]);
        }

        return result.ToArray();
    }

    // return the pct match instead of bool so we can sort the search items...
    public decimal CompareString(string SearchText, string FormText)
    {
        if (string.IsNullOrEmpty(SearchText) && string.IsNullOrEmpty(FormText))
            return 0.0M;//return true; //both empty, exact match
        else if (string.IsNullOrEmpty(SearchText) || string.IsNullOrEmpty(FormText))
            return 0.0M;// return false; //one is empty, one isnt -- not a match

        decimal matchPercent = Convert.ToDecimal(0.75);

        SearchText = SearchText.ToLower();
        FormText = FormText.ToLower();

        List<string> lstSearchText = Regex.Split(SearchText, @"\s", RegexOptions.IgnorePatternWhitespace).ToList();
        List<string> lstFormText = Regex.Split(FormText, @"\s", RegexOptions.IgnorePatternWhitespace).ToList();
        bool iterate = true;
        while (iterate)
        {
            iterate =
            lstSearchText.Remove(string.Empty) |
            lstSearchText.Remove(null) |
            lstFormText.Remove(string.Empty) |
            lstFormText.Remove(null);
        }
        int wordCount = lstFormText.Count;
        int excludedWords = 0;
        int matchedWords = 0;

        decimal res = 0.0M;

        //term - search we're comparing to the form
        //formWord - a word from the forms caption
        foreach (string term in lstSearchText)
        {
            if (term.Length < 2) //<2 characters is an insignificant search term
            {
                excludedWords++;
                continue;
            }
            for (int i1 = 0; i1 < lstFormText.Count; i1++)
            {
                res = CompareWord(term, lstFormText[i1]);
                if (res >= matchPercent)
                {
                    matchedWords++;
                    lstFormText.RemoveAt(i1);
                    break;
                }
            }
        }

        int denom = wordCount - excludedWords;
#if false
      if (denom > 0)
        return ((Convert.ToDecimal(matchedWords) / Convert.ToDecimal(denom)) >= matchPercent);
      else
        return false;
#else
        // return the pct match if it meets minimum criteria for match...
        if (denom > 0 && ((Convert.ToDecimal(matchedWords) / Convert.ToDecimal(denom)) >= matchPercent))
            return res;

        // did not meet minimum criteria; caller will see 0.0 and not add...
        return 0.0M;
#endif
    }

Thanks for your reply DdoubleD..............

>>In the code that follows, you will find my changes easily, because it is practically the only code that has comments!
:( I am pretty bad about not commenting

>>In the code that follows, you will find my changes easily, because it is practically the only code that has comments!
:( I am pretty bad about not commenting

Doh!--LOL.. Confessions are supposed to be good for the soul though,;)

>>In the code that follows, you will find my changes easily, because it is practically the only code that has comments!
:( I am pretty bad about not commenting

Likewise, my uni projects were always perfectly commented and beatifully designed...only problem was, i did ALL the commenting and drew up the UseCases/UML/etc in the last couple days before hand in haha.

I make a conscious effort to do it the right way around these days, but commenting always falls to the wayside : / God help anyone who tries to fix/update my code after i leave!

...
I make a conscious effort to do it the right way around these days, but commenting always falls to the wayside : / God help anyone who tries to fix/update my code after i leave!

Yea, it's usually people like me who come in after you leave and comment the hello out of it while trying to figure out what it does. :confused: The prevalent attitude I've encountered is: Job Security, ha, ha; but, management doesn't have a clue about what kind of learning curve you are leaving behind to others anyway--ha, ha--:D Anyway, it's usually someone like me that is able to come in and decipher the code and get all kinds of compliments, so it's not all bad. ;)

avirag, let me know if that problem with the duplicate keys is solved with those three lines I added...

Well this commenting problem happen with me also.....;)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.