【问题标题】:What design decision is better for calculating a prediction and a scoring system? [closed]哪种设计决策更适合计算预测和评分系统? [关闭]
【发布时间】:2011-09-30 20:26:53
【问题描述】:

我正在尝试制作一个应用程序,让用户根据他们的预测和实际结果填写预测和得分。

我有一个称为 GetPointsPrediction() 的方法。目前,预测具有以下形式:

Dictionary<int, Driver> predictions = new Dictionary<int, Driver>
{
    {1, new Driver(10, "Michael Schumacher")},
    {2, new Driver(8, "Jensen Button")},
    {3, new Driver(7, "Felipe Massa")},
    {4, new Driver(9, "Fernando Alonso")}
};

整数是用户认为驱动程序将完成的位置。现在,我需要能够根据预测和结果计算点数。要打分,我需要在结果中包含三个信息:位置、驱动程序和积分。

准确地在他们预测的位置完成比赛的车手获得满分。未在预测位置完成但进入前十名的车手将被扣分。

你看到的所有序号都是位置。

解决方案一:

有一个单独的结果集和一个字典,其中包含每个位置的点,将用作查找:

Dictionary<int, Driver> results = new Dictionary<int, Driver>
{
    {1, new Driver(10, "Michael Schumacher")},
    {2, new Driver(8, "Jensen Button")},
    {3, new Driver(9, "Fernando Alonso")}
};

Dictionary<int, int> points = new Dictionary<int, int>
{
    {1, 25},
    {2, 18},
    {3, 15},
    {4, 12},
    {5, 10}
};

解决方案 2:

合并点和结果。

Dictionary<int, Dictionary<int, Driver>> results = new Dictionary<int, Dictionary<int, Driver>>

解决方案 3:

想出某种可以容纳一切的类:

public class DriverResult
{
    public Driver Driver { get; private set; }
    public int Points { get; private set; }
    public int StartPosition { get; private set; }
    public int FinishPosition { get; private set; }
}

然后

IEnumerable<DriverResult> raceResults = new List<DriverResult>

我喜欢解决方案 3,但我觉得它不够连贯,名字也感觉不好。解决方案 2 可能很难真正使用,而解决方案 1 实际上为我提供了一种很好的方法,可以将正确预测的驱动程序与 Intersect 分开。

也许还有其他我没有想到的解决方案。关于这些设计决策的最佳实践是什么?

驱动类:

public class Driver : IEquatable<Driver>
    {
        public int DriverId { get; private set; }
        public string Name { get; private set; }

        public Driver(int driverId, string name)
        {
            DriverId = driverId;
            Name = name;
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as Driver);
        }

        public bool Equals(Driver other)
        {
            return other != null && other.DriverId == DriverId;
        }

        public override int GetHashCode()
        {
            return DriverId.GetHashCode();
        }
    }

【问题讨论】:

  • 我不太清楚你在做什么。 Driver 类中有什么?为什么你所有的索引都是连续的?如果是,为什么不使用数组而不是字典呢?例如,int points[] = new int[] { 25, 18, 15, 12, 10 };
  • 我添加了驱动程序类并解释了顺序的内容(它们是完成位置);我需要一本字典(我认为),因为我需要例如属于某个位置的点。
  • 但如果位置是连续的,那么您将使用数组而不是字典。字典(或 SortedLists)适用于数据稀疏且需要查找的情况。例如,您可以为自己的驱动程序使用字典,这样您就可以按 ID 查找,因为 ID 可能是 1 或 1002。
  • 这对于 Stack Overflow 来说有点过于本地化了。

标签: c# architecture c#-4.0 software-design


【解决方案1】:

由于预测是按位置顺序的,因此它们应该是一个数组。由于点也是按顺序排列的,所以它也应该是一个数组。使用字典没有任何意义。但是,如果您想按 ID 查找驱动程序,则需要为驱动程序创建一个 Dictionary 或 SortedList,其中 ID 是关键,而不是顺序的位置。所以你有两个数组:

Driver[] predictions = new Driver[]
{
    new Driver(10, "Michael Schumacher"),
    new Driver(8, "Jensen Button")
    new Driver(7, "Felipe Massa")
    new Driver(9, "Fernando Alonso")
};

位置为 1 的索引,例如predictions[0] 是对位置 1 的预测。类似地,对点使用数组:

int[] points = new int[] { 25, 18, 15, 12, 10 };

按位置的接入点 - 1,例如points[0] 是位置 1 的点数。

考虑将 DriverPoints 和 StartPosition 等其他字段添加到 Driver,而不是 DriverResults。然后你就可以更新数组中的 Driver 类了。

编辑:要存储各种比赛、测试、赛季等结果,请创建一个名为 DriverResults 的类,并让 RaceResults 或 SeasonResults 等类继承自它。将成员添加到驱动程序:

List<DriverResults> Results { get; set; }

现在您可以创建 SeasonResults 或 RaceResults 并将它们添加到此列表中,存储任意数量的结果。

【讨论】:

  • 是的,数组是个好主意。我想在 Driver 中有 DriverPoints 的问题在于有几种积分:一场比赛的积分、一个赛季的积分、一个职业生涯的积分等。但对于我来说,这是一场比赛的积分 -它真的属于Driver吗?在某些情况下,我可能需要车手中的一些东西,但与比赛本身无关(想想可能是车手的个人资料页面)。
  • 创建一个名为 DriverResults 的类。各种结果(RaceResults、TestResults、SeasonResults 等)都来自 DriverResults。然后,您可以向驱动程序“List Results”添加一个成员,并将所有这些内容存储在其中任意次数。
  • 感谢所有伟大的想法!
猜你喜欢
  • 2011-04-17
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 2014-02-26
  • 2010-09-07
  • 1970-01-01
相关资源
最近更新 更多