Я просто собираюсь добавить несколько комментариев к тому, что другие подчеркнули, и дать лучший алгоритм для того, что вы хотите.
Не используйте указатели здесь . Использование указателей не делает это с ++, это делает плохое кодирование. Если у вас есть книга, которая научила вас c ++ таким образом, выбросьте ее. То, что у языка есть особенность, не означает, что его следует использовать везде, где вы можете . Если вы хотите стать профессиональным программистом, вам нужно научиться использовать соответствующие части ваших языков для любого конкретного действия. Когда вам нужна структура данных, используйте ту, которая соответствует вашей деятельности. Указатели не являются структурами данных, они являются ссылочными типами, используемыми, когда вам нужен объект с временем жизни состояния, т.е. когда объект создается в одном асинхронном событии и уничтожается в другом. Если объект проживает свое время жизни без какого-либо асинхронного ожидания, он может быть смоделирован как объект стека и должен быть. Указатели никогда не должны подвергаться коду приложения, не будучи обернутым в объект, потому что стандартные операции (как новые) генерируют исключения, и указатели не очищают себя. Другими словами, указатели всегда должны использоваться только внутри классов и только тогда, когда необходимо реагировать динамически созданными объектами на внешние события класса (которые могут быть асинхронными).
Не используйте массивы здесь . Массивы - это простые однородные типы данных сбора времени жизни стека размера, известного во время компиляции. Они не предназначены для итерации. Если вам нужен объект, который позволяет итерацию, есть типы, которые имеют встроенные средства для этого. Однако сделать это с массивом означает, что вы отслеживаете переменную размера, внешнюю по отношению к массиву. Это также означает, что вы применяете внешнее по отношению к массиву, что итерация не будет расширяться после последнего элемента, используя вновь сформированное условие каждую итерацию (обратите внимание, что это отличается от простого управления размером - это управление инвариантом, причина, по которой вы создаете классы в первое место). Вы не можете повторно использовать стандартные алгоритмы, боретесь с распадом на указатель и вообще делаете хрупкий код. Массивы (опять же) полезны, только если они инкапсулированы и используются там, где единственным требованием является произвольный доступ к простому типу без итерации.
Не сортировать вектор здесь . Это просто странно, потому что это не очень хороший перевод с вашей первоначальной проблемы, и я не уверен, откуда она взялась. Не оптимизируйте рано, но не пессимируйте рано, выбрав плохой алгоритм. Здесь необходимо искать каждую строку внутри другой коллекции строк. Сортированный вектор является инвариантом (поэтому, опять же, подумайте о том, что нужно инкапсулировать) - вы можете использовать существующие классы из библиотек, такие как boost или roll свои собственные. Однако немного лучше в среднем использовать хеш-таблицу. С поиском с амортизацией O (N) (с размером N строки поиска - помните, что это число амортизированных сравнений за O (1), а для строк это O (N)), естественный первый способ перевода: Строка "должна сделать unordered_set<string>
вашим b
в алгоритме. Это меняет сложность алгоритма с O (NM log P) (теперь N - это средний размер строк в a
, M - размер коллекции a
и P - размер коллекции b
), до O ( NM). Если коллекция b
становится большой, это может быть весьма экономно.
Другими словами
gboolean foo(vector<string> const& a, unordered_set<string> const& b)
Обратите внимание, теперь вы можете передавать константу в функцию. Если вы создаете свои коллекции с учетом их использования, у вас часто есть потенциальная дополнительная экономия в будущем.
Смысл этого ответа в том, что вы действительно никогда не должны иметь привычку писать код, подобный опубликованному. Жаль, что есть несколько действительно (действительно) плохих книг, которые учат кодированию с такими строками, и это настоящий позор, потому что нет необходимости когда-либо выглядеть так ужасно. Он поддерживает идею о том, что c ++ является сложным языком, когда в нем есть действительно хорошие абстракции, которые делают это проще и с лучшей производительностью, чем многие стандартные идиомы в других языках. Примером хорошей книги, которая учит вас, как использовать всю мощь языка, чтобы не создавать вредных привычек, является «Ускоренный C ++» Кенига и Му.
Но также вы всегда должны думать о замечаниях, сделанных здесь, независимо от языка, который вы используете. Вы никогда не должны пытаться применять инварианты вне инкапсуляции - это был самый большой источник экономии от повторного использования в объектно-ориентированном дизайне. И вы всегда должны выбирать свои структуры данных, соответствующие их фактическому использованию. И всегда, когда это возможно, используйте всю мощь языка, который вы используете, чтобы избежать необходимости изобретать велосипед. C ++ уже имеет встроенное управление строками и сравнение, он уже имеет эффективные структуры поиска данных. Он может выполнять многие задачи, которые вы можете описать просто, просто закодировав, если вы немного подумаете над проблемой.