Приближается к O (1) (без времени инициализации)
Если вы действительно хотите решение O (1), я надеюсь, что вы не учитываете инициализацию.
Для инициализации:
- Построить отсортированный список всех дат в запрашиваемом диапазоне, которые являются допустимыми возвращаемыми значениями. (используя что-то вроде кода в ответе от Рика Гарнера)
- Создать хеш-таблицу с датами из приведенного выше списка, с ключом в качестве даты и индексом в списке в качестве значения
Код инициализации вам понадобится только один раз, и вы кешируете результат.
Для запроса / расчета
List<DateTime> validWorkdays = // ;
Dictionary<DateTime, int> lookupIndexOfValidWorkday = // ;
DateTime AddWorkdays(DateTime start, int count) {
var startIndex = lookupIndexOfValidWorkday[start];
return validWorkDays[startIndex + count];
}
Относительно извлечения из словаря :
Получение или установка значения этого свойства приближается к операции O (1).
O (n) по числу праздников
При условии, что список праздников отсортирован от самых старых до самых новых. ( Кредиты по будням формулы )
DateTime AddBusinessDay(DateTime start, int count, IEnumerable<DateTime> holidays) {
int daysToAdd = count + ((count/ 5) * 2) + ((((int)start.DayOfWeek + (count % 5)) >= 5) ? 2 : 0);
var end = start.AddDays(daysToAdd);
foreach(var dt in holidays) {
if (dt >= start && dt <= end) {
end = end.AddDays(1);
if (end.DayOfWeek == DayOfWeek.Saterday) {
end = end.AddDays(2);
}
}
}
return end;
}
Этот метод может быть оптимизирован.
Очень сложно создать простую формулу, которая просто вычисляет результат, как ответы на вопрос, с которым вы связаны. Потому что, когда вы приспосабливаетесь к праздникам, вы должны учитывать новые праздники, которые могут попасть в ваш диапазон. В выходные дни вы знаете, что между ними установлен фиксированный интервал.