0

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

规则是:

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

一些例子:

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);
            }
        }
    }
}
4

1 回答 1

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?
        }
于 2013-01-26T09:47:33.397 回答