Алгоритм:
В C #:
void Main()
{
var set = new [] {"A", "B", "C", "D" }; //, "E", "F", "G", "H", "I", "J" };
var kElement = 2;
for(var i = 1; i < Math.Pow(2, set.Length); i++) {
var result = Convert.ToString(i, 2).PadLeft(set.Length, '0');
var cnt = Regex.Matches(Regex.Escape(result), "1").Count;
if (cnt == kElement) {
for(int j = 0; j < set.Length; j++)
if ( Char.GetNumericValue(result[j]) == 1)
Console.Write(set[j]);
Console.WriteLine();
}
}
}
Почему это работает?
биекция между подмножествами n-элементного множества и n-битовых последовательностей.
Это означает, что мы можем выяснить, сколько подмножеств существует путем подсчета последовательностей.
, например, четыре приведенных ниже элемента могут быть представлены {0,1} X {0, 1} X {0, 1} X {0, 1} (или 2 ^ 4) различными последовательностями.
Итак, все, что нам нужно сделать, это считать от 1 до 2 ^ n, чтобы найти все комбинации. (Мы игнорируем пустое множество.) Затем переведите цифры в их двоичное представление. Затем замените элементы вашего набора на биты «on».
Если вы хотите получить только результаты k-элемента, только распечатывайте, когда k бит «включено».
(Если вы хотите, чтобы все подмножества вместо подмножеств k длины удаляли часть cnt / kElement.)
(Для доказательства см. бесплатную учебную программу MIT Mathematics for Computer Science, Lehman et al. , раздел 11.2.2. https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-042j-mathematics-for-computer-science-fall-2010/readings/ )
Ваш поток разделяет время ЦП с другими потоками. Спящий режим закончится, как только придет ваша очередь снова, и ядро заметит, что время ожидания истекло, поэтому это не так точно.
Загрузка процессора, приоритеты процессов, количество параллельных потоков, даже от других процессов, будут иметь влияние на него.
Thread.Sleep не предназначен для точного пробуждения. На самом деле сама архитектура Windows не предназначена для такого рода вещей.
Спящий поток и синхронизация / регулирование - это разные вещи, и с ними следует обращаться соответствующим образом. Засыпание потока - это общая задача, позволяющая системе предоставить другим потокам и процессам возможность выполнения, не конкретизируя это. С другой стороны, регулирование приложения или планирование задач, требующих точного времени, следует выполнять с помощью явного таймера.
Имейте в виду, что если вам нужны процессы или синхронизация с точностью до времени, вам будет сложно добиться этого с помощью обычного процесса в Windows. Вам нужно будет использовать приоритеты Windows в реальном времени для успешного достижения точного времени или регулирования, так как окна могут в любое время засыпать любой поток, если его вытесняет другой поток.
В одном приложении, где я хотел спать по крайней мере на x миллисекунд, я использовал код, похожий на:
public void Sleep(int milliseconds)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < milliseconds)
{
int timeout = milliseconds - stopwatch.ElapsedMilliseconds;
Thread.Sleep(timeout >= 0 ? timeout : 0);
}
stopwatch.Stop();
}
В ответ на то, насколько точен Thread.Sleep, он совсем неточен. Думаю, разрешение где-то около 10мс. Не гарантируется, что он сделает что-либо, кроме «примерно» такого времени.
Может быть, вам не следует полагаться на временную предвзятость, чтобы узнать, где вы успешно. Лучше посчитайте количество попыток и сравните его с этим:
int tries;
for(tries=0; tries<3; tries++)
{
Thread.Sleep(oneSecond);
}
Assert.GreaterOrEqual(tries, 3);
Быстро экспериментируя, я заметил, что фрагмент кода вроде ...
do {Debug.WriteLine (DateTime.Now.TimeOfDay.TotalMilliseconds.ToString ()); } while (1);
отображает одно и то же число несколько раз, затем переходит к новому числу, отображаемому несколько раз, и т. д. Разрыв между этими наборами чисел постоянно составляет 15,625 мс, что, как я заметил, составляет 1000/64.
Похоже, таймеры Windows имеют дискретность 1/64 секунды. Если вам нужно что-то лучшее, я чувствую вашу боль, но это рамки, в которые вы должны вписаться. (Windows не является ОС реального времени и не претендует на нее).