如何采取X量的问题,总结Y难度

我有一张桌子

问题 – >问题(字符串),难度(int,1-10)

我需要创建一个方法,如标题所示,需要X个问题,其难度应该总结为Y

例如:

getQuestions(2,10) – > Question1(diff:4),Question2(diff:6)

getQuestions(3,15) – > Question3(diff:5),Question4(diff:5),Question5(diff:5)

如何使用LINQ实现这样的function?

这是一种方法,使用此处的递归解决方案的修改版本: 查找所有可能的数字组合以达到给定的总和

首先,一个公共方法,它将进行一些快速validation,然后调用递归方法来获得结果:

 ///  /// Gets lists of numQuestions length of all combinations /// of questions whose difficulties add up to sumDifficulty ///  /// The list of questions to search /// The number of questions required /// The amount that the difficulties should sum to ///  public static List> GetQuestions(List questions, int numQuestions, int sumDifficulty) { if (questions == null) throw new ArgumentNullException("questions"); var results = new List>(); // Fail fast argument validation if (numQuestions < 1 || numQuestions > questions.Count || sumDifficulty < numQuestions * Question.MinDifficulty || sumDifficulty > numQuestions * Question.MaxDifficulty) { return results; } // If we only need single questions, no need to do any recursion if (numQuestions == 1) { results.AddRange(questions.Where(q => q.Difficulty == sumDifficulty) .Select(q => new List {q})); return results; } // We can remove any questions who have a difficulty that's higher // than the sumDifficulty minus the number of questions plus one var candidateQuestions = questions.Where(q => q.Difficulty <= sumDifficulty - numQuestions + 1) .ToList(); if (!candidateQuestions.Any()) { return results; } GetSumsRecursively(candidateQuestions, sumDifficulty, new List(), numQuestions, results); return results; } 

然后执行繁重的递归方法:

 private static void GetSumsRecursively(IReadOnlyList questions, int sumDifficulty, List candidates, int numQuestions, ICollection> results) { int candidateSum = candidates.Sum(x => x.Difficulty); if (candidateSum == sumDifficulty && candidates.Count == numQuestions) { results.Add(candidates); } if (candidateSum >= sumDifficulty) return; for (int i = 0; i < questions.Count; i++) { var remaining = new List(); for (int j = i + 1; j < questions.Count; j++) { remaining.Add(questions[j]); } var filteredCandidates = new List(candidates) {questions[i]}; GetSumsRecursively(remaining, sumDifficulty, filteredCandidates, numQuestions, results); } } 

这是一个示例用法:

 public static void Main() { const int numberOfQuestions = 3; const int sumOfDifficulty = 15; // Since I don't have your table, I'm using a list of objects to fake it var questions = new List(); for (int i = 1; i < 11; i++) { questions.Add(new Question {Difficulty = i % 10 + 1, QuestionString = "Question #" + i}); } var results = GetQuestions(questions, numberOfQuestions, sumOfDifficulty); // Write output to console to verify results foreach (var result in results) { Console.WriteLine("{0} = {1}", string.Join(" + ", result.Select(r => r.Difficulty)), sumOfDifficulty); } } 

只是这样你才能完成所有工作,这是我用来伪造你的桌子的问题类:

 internal class Question { public const int MinDifficulty = 1; public const int MaxDifficulty = 10; private int _difficulty; public int Difficulty { get { return _difficulty; } set { if (value < MinDifficulty) _difficulty = MinDifficulty; else if (value > MaxDifficulty) _difficulty = MaxDifficulty; else _difficulty = value; } } public string QuestionString { get; set; } }