找到表匹配的最佳方法

时间:2013-01-26 08:30:13

标签: c# match keyword

我需要一种基于多个关键词在对象列表中查找匹配行的方法。在下面的代码示例中,FindID()函数是我需要实现的函数。

规则是:

  1. 表中的某些行具有*作为值(通配符),这意味着它们将匹配任何值。
  2. 匹配的优先级是从左到右(即,匹配左侧的值更为重要)
  3. 一些例子:

    FindID("John", "Black", "Brown"); - 应该返回1,完成匹配

    FindID("John", "Red", "Green"); - 应该返回5(不是7),匹配“John”和其他两个通配符(*)

    FindID("John", "Red", "Brown"); - 应该返回6,匹配“John”和“Brown”以及一个通配符

    FindID("Brian", "Grey", "Grey"); - 应返回8,在三个通配符上匹配

    以下代码已完成,可以执行。

    有谁知道这样做的最佳方式?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace TableScan
    {
        class Program
        {
            public static TableClass _MyTable = new TableClass();
    
            public class TableRow
            {
                public int ID;
                public string Name;
                public string Hair;
                public string Eyes;
    
                public TableRow(int _ID, string _Name, string _Hair, string _Eyes)
                {
                    ID = _ID;
                    Name = _Name;
                    Hair = _Hair;
                    Eyes = _Eyes;
                }
            }
    
            public class TableClass
            {
                public List<TableRow> Table = new List<TableRow>();
            }
    
            static void Main(string[] args)
            {
                // ID       Name        Hair        Eyes
                // 1        John        Black       Brown
                // 2        Paul        Brown       Green
                // 3        Ringo       Blond       Blue
                // 4        George      Red         Blue
                // 5        John        *           *
                // 6        John        *           Brown
                // 7        *           Red         *
                // 8        *           *           *
                // 9        Paul        *           *
    
                CreateTable();
    
                ShowTable();
    
                FindID("John", "Black", "Brown");  // should return 1, complete match
    
                FindID("John", "Red", "Green");  // should return 5 (not 7), matched on "John" and the other two wildcards (*)
    
                FindID("John", "Red", "Brown");  // should return 6, matched on "John" and "Brown" and one wildcard
    
                FindID("Brian", "Grey", "Grey");  // should return 8, matched on three wildcard
    
                while (Console.ReadKey().Key == 0) { }
            }
    
            static int FindID(string _Name, string _Hair, string _Eyes)
            {
                // needs to be implemented
    
                return 0;
            }
    
            static void CreateTable()
            {
                _MyTable.Table.Add(new TableRow(1, "John", "Black", "Brown"));
                _MyTable.Table.Add(new TableRow(2, "Paul", "Brown", "Green"));
                _MyTable.Table.Add(new TableRow(3, "Ringo", "Blond", "Blue"));
                _MyTable.Table.Add(new TableRow(4, "George", "Red", "Blue"));
                _MyTable.Table.Add(new TableRow(5, "John", "*", "*"));
                _MyTable.Table.Add(new TableRow(6, "John", "*", "Brown"));
                _MyTable.Table.Add(new TableRow(7, "*", "Red", "*"));
                _MyTable.Table.Add(new TableRow(8, "*", "*", "*"));
                _MyTable.Table.Add(new TableRow(9, "Paul", "*", "*"));
            }
    
            static void ShowTable()
            {
                foreach(TableRow _TableRow in _MyTable.Table)
                {
                    Console.WriteLine("{0} {1} {2} {3}", _TableRow.ID, _TableRow.Name, _TableRow.Hair, _TableRow.Eyes);
                }
            }
        }
    }
    

1 个答案:

答案 0 :(得分:0)

今晚好漂亮,这是基于评论的解决方案,请参阅http://ideone.com/rR46Ws

static bool match(TableRow row, string _Name, string _Hair, string _Eyes)
        {
                return (row.Name == _Name || row.Name == "*") && (row.Hair == _Hair || row.Hair == "*") && (row.Eyes == _Eyes || row.Eyes == "*");
        }

        static int score(TableRow row)
        {
                //can assume these already "match"
                var score = 0;
                score +=  row.Name == "*" ? 1000 : 2000; 
                score +=  row.Hair == "*" ? 100 : 200; 
                score +=  row.Eyes == "*" ? 10 : 20; 
                return score;
        }

        static int FindID(string _Name, string _Hair, string _Eyes)
        {

            var s = from row in _MyTable.Table
                        where match(row, _Name, _Hair, _Eyes)
                        orderby score(row) descending
                        select row;


            var match = s.FirstOrDefault();
            if(match != null) return match.ID;
            return -1; //i guess?
        }