如何采取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; } }