Найдите самое близкое время из списка времен

Адвокат языка вопрос. Hmkay.

Мой персональный top3:

  1. нарушение строгого правила
  2. искажения, нарушающего строгое правило
  3. искажения, нарушающее строгое правило

    искажения:-)

, Редактирование Вот является небольшим примером, который делает это неправильно дважды:

(принимают 32 бита ints и прямой порядок байтов)

float funky_float_abs (float a)
{
  unsigned int temp = *(unsigned int *)&a;
  temp &= 0x7fffffff;
  return *(float *)&temp;
}

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

Однако результатом создания указателя на объект путем кастинга от одного типа до другого не является допустимый C. Компилятор может предположить, что указатели на различные типы не указывают на тот же блок памяти. Это верно для всего вида указателей кроме пустоты*, и символ* (мыс знака не имеет значения).

В случае выше я делаю это дважды. Однажды для получения международного псевдонима для плавания a, и однажды преобразовать значение назад для плавания.

существует три допустимых способа сделать то же.

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

float funky_float_abs (float a)
{
  float temp_float = a;
  // valid, because it's a char pointer. These are special.
  unsigned char * temp = (unsigned char *)&temp_float;
  temp[3] &= 0x7f;
  return temp_float;
}

Использование memcopy. Memcpy берет пустые указатели, таким образом, он вызовет искажение также.

float funky_float_abs (float a)
{
  int i;
  float result;
  memcpy (&i, &a, sizeof (int));
  i &= 0x7fffffff;
  memcpy (&result, &i, sizeof (int));
  return result;
}

третий допустимый путь: используйте объединения. Это явно не не определено начиная с C99:

float funky_float_abs (float a)
{
  union 
  {
     unsigned int i;
     float f;
  } cast_helper;

  cast_helper.f = a;
  cast_helper.i &= 0x7fffffff;
  return cast_helper.f;
}
20
задан Nick DeMayo 18 November 2009 в 16:13
поделиться

10 ответов

Примерно так:

DateTime fileDate, closestDate;
ArrayList theDates;
long min = long.MaxValue;

foreach (DateTime date in theDates)
 if (Math.Abs(date.Ticks - fileDate.Ticks) < min)
 {
   min = Math.Abs(date.Ticks - fileDate.Ticks);
   closestDate = date;
 }
7
ответ дан 29 November 2019 в 22:33
поделиться
var closestTime = listOfTimes.OrderBy(t => Math.Abs((t - fileCreateTime).Ticks))
                             .First();

Если вы не хотите накладных расходов на производительность вызова OrderBy , вы можете использовать что-то вроде метода расширения MinBy из MoreLINQ вместо:

var closestTime = listOfTimes.MinBy(t => Math.Abs((t - fileCreateTime).Ticks));
49
ответ дан 29 November 2019 в 22:33
поделиться
var closestTime = (from t in listOfTimes
                   orderby (t - fileInfo.CreationTime).Duration()
                   select t).First();
6
ответ дан 29 November 2019 в 22:33
поделиться
var creationTimes = new [] {DateTime.Now.AddDays(-1), DateTime.Now.AddDays(-2)};
FileInfo fi = new FileInfo("C:/test.xml");
var closestTime = creationTimes
    .OrderBy(c => Math.Abs(c.Subtract(fi.CreationTime).Days))
    .First();
0
ответ дан 29 November 2019 в 22:33
поделиться
var min = listoftimes.Select(
    x => new { diff = Math.Abs((x - timeoffile).Ticks), time = x}).
    OrderBy(x => x.diff).
    First().time;

Примечание. Предполагается, что хотя бы одна запись в listoftimes .

0
ответ дан 29 November 2019 в 22:33
поделиться

Как часто вы будете делать это в один и тот же список раз? Если вы делаете это только один раз, Самый быстрый способ - это просто просмотреть список и отследить ближайшее время, которое вы еще видели. Когда / если вы встретите более близкое время, замените «самое близкое» на более близкое.

Если вы делаете это очень часто, вы, вероятно, захотите отсортировать список, а затем использовать двоичный поиск.

5
ответ дан 29 November 2019 в 22:33
поделиться

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

1
ответ дан 29 November 2019 в 22:33
поделиться

получайте разницу в творчестве вашего файла и каждый раз в вашем списке и отсортируйте абсолютное значение каждой разницы во времени. первым должен быть ответ, который вы ищете.

2
ответ дан 29 November 2019 в 22:33
поделиться

Не ответ, а вопрос относительно различных LINQ решения, предложенные выше. Насколько эффективен LINQ? Я еще не написал никаких "настоящих" программ с LINQ, поэтому не уверен в производительности.

В этом примере "listOfTimes" collection подразумевает, что мы уже перебирали некоторые объекты на основе файловой системы, чтобы собрать время. Было бы более эффективно проводить анализ во время итерации, а не позже в LINQ? Я понимаю, что эти решения могут быть более «элегантными» или красиво абстрагироваться от идеи «коллекция как база данных», но я предпочитаю эффективность (хотя и должна быть удобочитаемой) в моем программировании. Просто интересно, может ли стоимость LINQ перевесить здесь элегантность?

но я предпочитаю эффективность (хотя и должна быть удобочитаемой) в своем программировании. Просто интересно, может ли стоимость LINQ перевесить здесь элегантность?

но я предпочитаю эффективность (хотя и должна быть удобочитаемой) в своем программировании. Просто интересно, может ли стоимость LINQ перевесить здесь элегантность?

1
ответ дан 29 November 2019 в 22:33
поделиться

Принятый ответ полностью неверен. Вам нужно примерно следующее:

  DateTime fileDate, closestDate;
  List<DateTime> theDates;

  fileDate = DateTime.Today;       //set to the file date
  theDates = new List<DateTime>(); //load the date list, obviously

  long min = Math.Abs(fileDate.Ticks - theDates[0].Ticks);
  long diff;
  foreach (DateTime date in theDates)
  {
    diff = Math.Abs(fileDate.Ticks - date.Ticks);
    if (diff < min)
    {
      min = diff;
      closestDate = date;
    }
  }
8
ответ дан 29 November 2019 в 22:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: