Альтернатива else, если для случайного числа С#.net

Есть ли более короткий способ проверить мое случайное число от 1 до 100 (catNum) против этой таблицы животных? Это не выглядит так плохо, но у меня есть еще несколько больших таблиц для работы, я бы хотел использовать меньше строк, чем мне пришлось бы использовать приведенную ниже инструкцию:

if (catNum < 36) { category = "Urban"; }
 else if (catNum < 51) { category = "Rural"; }
 else if (catNum < 76) { category = "Wild"; }
 else if (catNum < 86) { category = "Wild Birds"; }
 else { category = "Zoo"; }

Пример дополнительных таблиц:

4 ответа

Я предпочитаю использовать что-то вроде этого вместо многих классов if/else A

class Category
{
 public int Min { get; set; }
 public int Max { get; set; }
 public string Name { get; set; }
}

Инициализируйте категории один раз и заполните его своими значениями

var categories = new List<category>();
</category>

и, наконец, метод разрешения категории

public static string Get(int currentValue)
{
 var last = categories.Last(m => m.Min < currentValue);
 //if the list is ordered 
 //or
 // var last = categories.FirstOrDefault(m => m.Min <= currentValue && m.Max >= currentValue);
 return last?.Name;
}


string[] animals = new string[] { "Urban", "Rural", "Wild", "Wild Birds", "Zoo" };
int[] table = new int[] { 35, 50, 75, 85 }; 
for (int catNum = 10; catNum <= 100; catNum += 10)
{
 int index = Array.BinarySearch(table, catNum);
 if (index < 0) index = ~index;
 Console.WriteLine(catNum + ": " + animals[index]);
}

Выполнить онлайн: https://dotnetfiddle.net/yMeSPB


Один из вариантов заключается в создании полного списка элементов, тогда вы можете просто выбрать один случайным образом по индексу:

var categories =
 Enumerable.Repeat("Urban", 35)
 .Concat(Enumerable.Repeat("Rural", 15))
 .Concat(Enumerable.Repeat("Wild", 25))
 .Concat(Enumerable.Repeat("Wild Birds", 10))
 .Concat(Enumerable.Repeat("Zoo", 15))
 .ToArray();

var category = categories[45]; //Rural;


Да, это хорошо изученная проблема, и есть решения, которые более эффективны, чем цепочка if-else, которую вы уже обнаружили. Подробнее см. Https://en.wikipedia.org/wiki/Alias_method.

Мой совет: построить общий тип интерфейса, который представляет собой вероятность IDistribution - скажем, IDistribution. Затем напишите дискретную реализацию дистрибутива, которая использует метод псевдонима. Инкапсулируйте работу механизма в класс распределения, а затем на сайте использования у вас есть только конструктор, который позволяет вам сделать дистрибутив, и метод T Sample() который дает вам элемент дистрибутива.

Я замечаю, что в вашем примере у вас может быть байесовская вероятность, т.е. P(Dog | Urban). Вероятная монада - идеальный механизм для представления этих вещей, потому что мы переформулируем P(A|B) как Func<b, idistribution<a="">></b,> Итак, что у нас получилось? У нас есть IDistribution, у нас есть функция от Location to IDistribution, и мы тогда узнаем, что мы собрали их через операцию привязки на вероятностной монаде. Это означает, что в С# мы можем использовать LINQ. SelectMany - операция привязки последовательностей, но она также может использоваться как операция привязки на любой монаде!

Теперь, учитывая это, упражнение: какова условная вероятностная операция в LINQ?

Помните, что цель состоит в том, чтобы сделать код на сайте вызова похожим на выполняемую операцию. Если вы логически выполняете выборку из дискретного распределения, тогда у вас есть объект, который представляет собой дискретные распределения и образец из него.

licensed under cc by-sa 3.0 with attribution.