У меня есть функция, которая читает файлы в папке (я использую boost для этого). Я также пытаюсь сохранить только 2 файла (они являются файлами журналов, поэтому они вращаются, и я не хочу сохранять старые журналы = журналы в третьем файле). Я храню имена файлов в списке, но поскольку чтение не выполняется во временном порядке создания, мне нужно отсортировать список.
я знаю это
Векторы хороши:
- Доступ к отдельным элементам по индексу положения (постоянное время).
- Итерация по элементам в любом порядке (линейное время).
- Добавьте и удалите элементы со своего конца (время с постоянной амортизацией).
а также
Преимущества для перечисления контейнеров:
- Эффективная установка и удаление элементов в любом месте контейнера (постоянное время).
- Эффективные движущиеся элементы и блок элементов внутри контейнера или даже между различными контейнерами (постоянное время).
- Итерация по элементам в прямом или обратном порядке (линейное время).
Я не уверен, что это лучший способ сделать это: используя список или вектор?
Должен ли я
std::is_sorted
, это нормально, если вы не сортируете каждый раз?Дополнительная информация:
Поскольку в ротации файла boost нет состояния "удалить файл, если слишком много", только "на диске достаточно свободного места", я выполнил этот этап хранения двух последних файлов или удалив самый старый каждый раз, когда новый и есть 2 файла журнала. Поэтому каждый раз, когда создается новый файл журнала, я проверяю список файлов, и если их достаточно (2 или более), просто удалите старые (ые) файлы. Поскольку имена файлов имеют logs_%N.log
, я не знаю, является ли файл logs_X1.log
старше logs_X2.log
например: я перезапускаю приложения, есть файлы logs_51.log, logs_52.log, какой из них будет удален? Предположим, что он собирается удалить logs_51.log и создать logs_0.log, если я его снова заново запустил, будут logs_52.log и logs_0.log. Какой из них будет удален сейчас?)
Вот почему мне нужен вид, потому что приложение может перезагрузиться, и я прочитал существующие файлы, завершает ту, которая имеет больше места, а затем создает новую.
Фактически я использовал Boost для сортировки файлов в последнем измененном виде:
bool Logger::compareAccessTime(const std::string& path1In, const std::string& path2In)
{
return (fs::last_write_time(fs::path(path1In)) < fs::last_write_time(fs::path(path2In)));
}
где fs = boost::filesystem
И поскольку я использовал список строк, я не изменил весь код, но при инициализации списка добавил list::sort(compareAccessTime)
. Мне это нужно только в начале приложения, потому что тогда я добавляю в конец и удаляю с начала.
В этом конкретном случае, когда контейнер будет иметь ~ 2 элемента, это не имеет значения, один маленький бит. Время, затрачиваемое на перечисление файлов и удаление их, будет на несколько порядков медленнее, чем ваш выбор алгоритма и структуры данных. Просто поместите имена файлов в std::vector
, используйте std::sort
(который сортирует ваши имена файлов журналов, чтобы первые были на первом месте), а затем удалите первые элементы N-2. Работа выполнена.
Но для некоторых общих советов:
В наши дни общий совет, похоже, заключается в том, что std::vector
лучше, чем std::list
даже для многих вещей. std::list
выглядит так, как будто это было бы полезно, в основном из-за того, что это непрерывное хранилище, дружелюбный.
Можно построить тесты, которые будут показывать std::list
быстрее, но вы не ошибетесь, если вы выберете std::vector
для всего!
Если вам нужно поддерживать контейнер с течением времени и всегда нужно иметь возможность удалить самый маленький/самый большой элемент, std::priority_queue
может быть хорошей идеей.
Если вам нужно найти N наименьших/наибольших элементов в контейнере, std::partial_sort
- это алгоритм для этого; он будет быстрее, чем полный std::sort
потому что это не тратит усилий на сортировку элементов, которые вам не нужны.
Но, как и в случае с такими вопросами общей производительности, единственный правильный ответ должен быть "попробуй и посмотри", я боюсь!
Редактировать: изначально я предложил boost::circular_buffer
так как это проблема, но теперь ясно, что это не хорошее предложение, так как упорядочение должно быть создано путем сортировки, а не с помощью порядка вставки.
boost::circular_buffer
на самом деле не то, что вы ищете - я обновлю свой ответ. Если вы ищете всегда отсортированный контейнер, std::priority_queue
может быть более подходящим. Но на самом деле, я бы лично реализовал это, поместив имена файлов в std::vector
, отсортировав их с помощью std::sort
, затем итерируя по первым N-2 элементам и удалив их; дело сделано. Я гарантирую вам, что перечисление и удаление файлов будет на много порядков медленнее, чем ваш выбор структуры данных.
Никто на самом деле не понимает это, парень должен сравнить имя 2 файла, а не уроки структуры данных
используйте строку :: сравните, чтобы сравнить файлы, да, это будет сравнивать эти числа в конце ваших лог файлов, так что не беспокойтесь об этом
Вот как это работает
value=String.Compare(filenameA,filenameB)
If value<0 then print("filenameA is smaller than filenameB")
If value>0 then print("a is bigger than b")
If value=0 then print("a equals b")
oh и о выборе структуры данных, вам не нужно заботиться об эффективности или проблемах производительности, я имею в виду, что вы просто индексируете 2 файла по имени, простой и скромный массив будет делать трюк
здесь пример о том, как это сделать
putNewFileMethod(FileType* arrayofFiles,FileType MynewFile)'
{
String nameOfFile0=arrayOfFiles[0].method_that_retrieves_the_filename();
String nameOfFile1=arrayOfFiles[1].method_that_retrieves_the_filename();//you can search for a method of this kind in the docs of the api you are using,'
int value=String.Compare(nameOfFile0,nameOfFile1);
If( value<0)
arrayOfFiles[0]=MynewFile;
else arratOfFiles[1]=MynewFile;
}
Дополнительные замечания:
Вы можете использовать круговой массив из двух позиций, что не требует сортировки по файлам, но вы упомянули что-то о перезапуске приложения, поэтому я предполагаю, что это не оптимальное решение для вас (если вы хотите использовать пример кругового массива/буфера просто скажи мне)
Структуры данных не имеют функции сортировки стропин, по крайней мере, большинство из них, поэтому вам просто нужно сделать один из своих
last_write_time()
, я last_write_time()
свой подход. А по поводу вашего ответа я не очень согласен со сравнением строк, пример, который я добавил последним, является причиной, почему