فرض کنید 3 تا کاراکتر a و b و c دارید . حال می خواهید الگوریتمی بنویسید که تمام این کاراکتر ها را با یکدیگر ترکیب کند . اولین شرط حائز اهمیت تکراری نبودن ترکیب هاست و دومین شرط ترکیب کردن تمام حالت های موجود است .
شرط : (“A”, “B”, “C”, if k=2 (n=3 in this case))
روش اول
آنچه که در قطعه کد زیر سعی شده است این بوده که تمام حالت های مجموعه مشخص شده را بدست بیاوریم.
همچنین برای کسب اطلاعات بیشتر می توانید از لینک زیر بازدید کنید :
ساخت یک لیست ترکیبی منحصربه فرد در سی شارپ
قطعه کدی که در زیر مشاهده می کنید توسط برنامه کامپایلر به جهت تست آزمایش شده و خروجی صحیح مدنظر را بدست آورد.
static void Main(string[] args) { var list = new List<string> { "a", "b", "c", "d", "e" }; var result = GetPermutations(list, 3); foreach (var perm in result) { foreach (var c in perm) { Console.Write(c + " "); } Console.WriteLine(); } Console.ReadKey(); } static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> items, int count) { int i = 0; foreach (var item in items) { if (count == 1) yield return new T[] { item }; else { foreach (var result in GetPermutations(items.Skip(i + 1), count - 1)) yield return new T[] { item }.Concat(result); } ++i; } }
و در نهایت پس از اجرای برنامه خروجی به صورت زیر خواهد بود :
a b c a b d a b e a c d a c e a d e b c d b c e b d e c d e
روش دوم
می توانید از قطعه کد زیر و خروجی تولید شده استفاده کنید :
public IActionResult Index() { var list = new List<string> { "a", "b", "c", "d", "e" }; List<string> ret = GetAllCombinations(list).OrderBy(_ => _).ToList(); return View(); } static IEnumerable<string> GetAllCombinations(IEnumerable<string> list) { return list.SelectMany((mainItem, mi) => list.Where((otherItem, oi) => mi < oi) .Select(otherItem => mainItem + otherItem)); }
و در نهایت پس از اجرای برنامه خروجی به صورت زیر خواهد بود :
ab ac ad ae bc bd be cd ce de
روش سوم
می توانید از قطعه کد زیر و خروجی تولید شده استفاده کنید :
توجه داشته باشید که این قطعه کد بهینه شده نیست و نباید از آن برای مجموعه های بزرگ یا حلقه های تودرتو استفاده شود. قابل ذکر است که آرایه های کوتاه چندین بار ایجاد می شوند . به خواست خودتان برنامه را ویرایش کنید .
static class LinqExtensions { public static IEnumerable<IEnumerable<T>> CombinationsWithoutRepetition<T>( this IEnumerable<T> items, int ofLength) { return (ofLength == 1) ? items.Select(item => new[] { item }) : items.SelectMany((item, i) => items.Skip(i + 1) .CombinationsWithoutRepetition(ofLength - 1) .Select(result => new T[] { item }.Concat(result))); } public static IEnumerable<IEnumerable<T>> CombinationsWithoutRepetition<T>( this IEnumerable<T> items, int ofLength, int upToLength) { return Enumerable.Range(ofLength, Math.Max(0, upToLength - ofLength + 1)) .SelectMany(len => items.CombinationsWithoutRepetition(ofLength: len)); } }
foreach (var c in new[] {"a","b","c","d"}.CombinationsWithoutRepetition(ofLength: 2, upToLength: 4)) { Console.WriteLine(string.Join(',', c)); }
و در نهایت پس از اجرای برنامه خروجی به صورت زیر خواهد بود :
a,b a,c a,d b,c b,d c,d a,b,c a,b,d a,c,d b,c,d a,b,c,d
روش چهارم
می توانید از قطعه کد زیر و خروجی تولید شده استفاده کنید :
var list = new List<string> { "a", "b", "c", "d", "e" }; GetAllCombinations(list).OrderBy(_ => _).ToList().ForEach(Console.WriteLine); static IEnumerable<string> GetAllCombinations(IEnumerable<string> list) { return list.SelectMany(mainItem => list.Where(otherItem => !otherItem.Equals(mainItem)) .Select(otherItem => mainItem + otherItem)); }
و در نهایت پس از اجرای برنامه خروجی به صورت زیر خواهد بود :
ab ac ad ae ba bc bd be ca cb cd ce da db dc de ea eb ec ed