Я думаю, вам просто нужно заставить компаратор сравнивать только длину префикса с такими элементами:
std::vector<std::string> v
{
"C:/users/andy/documents/screenshot.jpg",
"C:/users/bob/desktop/file.txt",
"C:/users/bob/desktop/picture.png",
"C:/users/bob/desktop/video.mp4",
"C:/users/john/desktop/note.txt",
};
std::sort(std::begin(v), std::end(v));
std::string const prefix = "C:/users/bob/desktop/";
auto lb = std::lower_bound(std::begin(v), std::end(v), prefix);
// For the upper bound we want to view the vector's data as if
// every element was truncated to the size of the prefix.
// Then perform a normal match.
auto ub = std::upper_bound(lb, std::end(v), prefix,
[&](std::string const& s1, std::string const& s2)
{
// compare UP TO the length of the prefix and no farther
if(auto cmp = std::strncmp(s1.data(), s2.data(), prefix.size()))
return cmp < 0;
// The strings are equal to the length of the prefix so
// behave as if they are equal. That means s1 < s2 == false
return false;
});
// make the answer look like we used std::equal_range
// (if that's what's needed)
auto range = std::make_pair(lb, ub);
for(auto itr = range.first; itr != range.second; ++itr)
std::cout << *itr << '\n';
Вывод:
C:/users/bob/desktop/file.txt
C:/users/bob/desktop/picture.png
C:/users/bob/desktop/video.mp4
Чтобы объяснить, почему это работает, представьте, что вы берете вектор и сортируете его. Затем представьте, что вы посещаете каждый элемент и усекаете его до длины префикса. У вас останется отсортированный вектор без элементов длиннее префикса. В этот момент простой std::equal_range
сделает то, что вам нужно. Таким образом, все, что нам нужно сделать, это создать компаратор, который ведет себя как если бы элементы контейнера были усечены до длины префикса, и использовать этот компаратор в нашем std::equal_range
поиске ( или двойной std::lower_bound/upper_bound
поиск).
person
Galik
schedule
28.12.2017
std::equal_range
с вызываемым объектом сравнения кажется достаточной для задачи. Просто закодируйте объект сравнения, который реализует сравнение, соответствующее префиксу. Вам придется тщательно кодировать объект сравнения с отдельными реализациямиcomp(element, value)
иcomp(value, element)
. , чтобы вернуть правильный результат сравнения. - person Sam Varshavchik   schedule 28.12.2017bool
, указывающее, сортируется ли полная строка перед префиксом. Это смехотворно тривиально, и после того, как вы написали, вы уже сделали 50%. Остальные 50% — это функция, которая принимает префикс и полную строку и возвращаетtrue
, если префикс сортируется перед полной строкой. Задача решена. - person Sam Varshavchik   schedule 28.12.2017substr
использовалstd::string.compare
, но мне было понятнее, когда я смотрел на него. пожал плечами - person Retired Ninja   schedule 28.12.2017std::string
. Затем я могу различать два типа функций сравнения и реализовывать дваoperator()
в пользовательском классе компаратора, сравнивая префикс со строкой и префикс со строкой. - person Sam Varshavchik   schedule 28.12.2017C:\users\bob\desktop\picture.png
почему его нельзя вернуть? - person Killzone Kid   schedule 28.12.2017<=
или>=
нарушает строгое требование слабого порядка для сравнения. Этот ответ объясняет это лучше, чем я мог. :) stackoverflow.com/a/981299/920069 - person Retired Ninja   schedule 28.12.2017