2017-02-03 4 views
0

Есть ли способ найти и заменить подмножество символа char */string в наборе?Подстрока элемента в наборе

Пример:

std::set<char*> myset; 
myset.insert("catt"); 
myset.insert("world"); 
myset.insert("hello"); 

it = myset.subsetfind("tt"); 
myset.replace(it, "t"); 
+4

Для ассоциативных контейнеров вы не должны использовать указатель в качестве ключа, так как тогда это будет *** указатель ***, который является ключом, а не данными, на которые он указывает. Если вы хотите, чтобы ключ был строкой, вы должны использовать 'std :: string'. –

ответ

0

Вы могли использовать std::find_if с функцией предикат/функтора/лямбда, который ищет подстроку вы хотите.

1

Есть по крайней мере три причины, почему это не сработает.

  1. std::set обеспечивает только средства для поиска набора для значения, которое сравнивает в равной степени к значению идет поиск, а не к значению, которое соответствует некоторой произвольной части стоимости.

  2. Показанная программа - неопределенное поведение. Строковый литерал, такой как «привет», это const char *, а не char *. Никакой самоуважительный компилятор C++ не позволит вам вставить const char * в контейнер char * s. И вы не можете изменять значения const, по определению, в любом случае.

  3. Значения в std::set не могут быть изменены. Чтобы произвести изменение существующего значения в наборе, оно должно быть erase() d, затем новое значение insert() ed.

std::set просто не подходит для целей, которые вы пытаетесь выполнить.

+0

К сожалению, ICC, GCC и Clang компилируются только с GCC и Clang, выдавая предупреждение. – NathanOliver

1

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

Вам необходимо начать с набора вещей, которые вы можете изменить. Затем вам нужно найти элемент, удалить его из набора, изменить его, а затем снова вставить результат обратно в набор.

std::set<std::string> myset {"catt", "world", "hello"}; 
auto pos = std::find_if(myset.begin(), myset.end(), [](auto const &s) { return s.find("tt");}; 

if (pos != myset.end()) { 
    auto temp = *pos; 
    myset.remove(pos); 
    auto p= temp.find("tt"); 
    temp.replace(p, 2, "t"); 
    myset.insert(temp); 
} 
1

Вы не можете изменять элементы внутри набора.

Вы можете найти строки, содержащие подстроку, с помощью std::find_if. Как только вы найдете соответствующие элементы, вы можете удалить их из набора и добавить измененную копию строки, а подстроку заменить чем-то другим.

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

PPS. Неявное преобразование строкового литерала в char* устарело, поскольку C++ был стандартизирован, и поскольку C++ 11 такое преобразование плохо сформировано.

PPPS. Компаратор по умолчанию не будет прав, если вы используете указатели в качестве типа элемента. Вместо этого я рекомендую вам использовать std::string. (A strcmp подход, основанный на компараторе, также будет возможен, хотя гораздо более подвержен ошибкам памяти).

Смежные вопросы