2011-10-10 2 views
1

Итак, у нас есть набор имен файлов \ URL-адресов, таких как file, folder/file, folder/file2, folder/file3, folder/folder2/fileN и т. Д. Нам дается строка типа folder/. Мы хотим найти folder/file, folder/file2, folder/file3, и наиболее интересным folder/folder2/ (мы не хотим, чтобы список содержимого forlder2 показывал, что он существует и его можно искать). Возможно ли это с помощью STL и Boost, и как это сделать?Наличие std :: set с именами файлов (a, f/a, f/b, f/f/c и т. Д.), Как указать каталог по заданному f /?

Ups - только что узнал, что я уже loocked на этот раз некоторое время назад here ... но нету нашел правильный ответ еще ...

+0

Попробуйте 'substr()'. Подходящей структурой данных будет дерево * префиксов * (или «trie»), но для небольшого количества элементов, которые не должны быть необходимы. –

+0

Почему у вас это в std :: set? Создайте собственный пользовательский класс для ваших требований. – balki

+1

Возможный дубликат [set : как перечислить строки, начинающиеся с заданной строки и заканчивающиеся на '/' ?](http://stackoverflow.com/questions/7169320/setstring-how-to-list-not-strings- пуско-с-Given-струна-и-окончание-с) – Rella

ответ

1

Это звучит как отличная возможность использовать регулярные выражения вещи в НЧ/C++ 11

что-то вроде

std::set<std::string> theSet; 
// Get stuff into theSet somehow 

const std::string searchFor= "folder/"; 

std::set<std::string> matchingSet; 
std::for_each(std::begin(theSet), std::end(theSet), 
       [&matchingSet, &searchFor] (const std::string & s) 
{ 
    if (/* the appropriate code to do regex matching... */) 
     matchingSet.insert(s); // or the match that was found instead of s 
}); 

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

1

Относительно просто реализация C++ 11. Это можно легко изменить на C++ 03. (caveat: не скомпилировали или не тестировали это).

std::set<std::string> urls;   // The set of values you have 
std::string key_search = "folder/"; // text to search for 

std::for_each(
    urls.begin(), 
    urls.end(), 
    [&key_search] (const std::string& value) 
{ 
    // use std::string::find, this will only display 
    // strings that match from the beginning of the 
    // stored value: 
    if(0 == value.find(key_search)) 
     std::cout << value << "\n"; // display 
}); 
1

заказанных контейнеры имеет набор методов, которые весьма полезны в поиске диапазона итераторов: lower_bound и upper_bound. В вашем случае вы хотите использовать:

std::for_each(
    path_set.lower_bound("folder/"), 
    path_set.upper_bound("folder0"), // "folder" + ('/'+1) 
    ...); 
Смежные вопросы