Привет! У меня возникла проблема при решении задач на codewars. Я обнаружил, что мой код компилируется успешно в Visual Studio (MVS) с использованием стандарта C++ 17, но на сайте codewars (и в других онлайн-компиляторах) результат отличается.
Я ожидаю, что функция is_merge должна возвращать true в обоих случаях, но в MVS я получаю этот результат, а на codewars она возвращает false. Я подозреваю, что это может быть связано с методом find, но так как я новичок в программировании, не уверен.
Вот мой код:
<pre><code class="cpp">#include <iostream>
#include <unordered_map>
bool is_merge(const std::string& s, const std::string& part1, const std::string& part2)
{
if (s.size() < part1.size() + part2.size()) return false;
std::string sCopy = s;
std::unordered_multimap<int, char> part1map;
std::unordered_multimap<int, char> part2map;
int index = 0;
int order = 0;
for (auto& letter : part1)
{
part1map.emplace(index, letter);
++index;
}
index = 0;
for (auto& letter : part2)
{
part2map.emplace(index, letter);
++index;
}
for (auto& elem : part1map)
{
if (sCopy.find(elem.second) != std::string::npos && elem.first >= order)
{
sCopy.erase(sCopy.find(elem.second), 1);
order = elem.first;
}
}
order = 0;
for (auto& elem : part2map)
{
if (sCopy.find(elem.second) != std::string::npos && elem.first >= order)
{
sCopy.erase(sCopy.find(elem.second), 1);
</code></pre>
Судя по вашему описанию и коду, у вас могут возникать различия в результате работы вашей функции `is_merge` из-за особенностей работы с методами `find` и `erase` в сочетании с тем, как вы обрабатываете символы из строк `part1` и `part2`. Давайте рассмотрим несколько важных моментов, которые могут привести к проблемам с вашей реализацией.
1. **Удаление символов из строки**: Когда вы удаляете символ из `sCopy` с помощью метода `erase`, индексы для оставшихся символов изменяются. Это может привести к тому, что вы не будете находить следующие вхождения символов, даже если они есть, потому что `find` будет возвращать индексы для строки, которая уже изменилась.
2. **Проблемы с порядком**: Порядок обработки символов может сыграть значительную роль. Ваш алгоритм требует, чтобы символы `part1` и `part2` встречались в правильном порядке в строке `s`. Однако, если одинаковые символы присутствуют в обеих частях, а они удаляются из `sCopy`, это может нарушить логику.
Вот один из подходов для пересмотра вашего алгоритма, чтобы учесть эти нюансы:
```cpp
#include <iostream>
bool is_merge(const std::string &s, const std::string &part1, const std::string &part2) {
if (s.size() < part1.size() + part2.size()) return false;
size_t i = 0, j = 0, k = 0;
while (k < s.size()) {
if (i < part1.size() && s[k] == part1[i]) {
++i;
} else if (j < part2.size() && s[k] == part2[j]) {
++j;
} else {
return false;
}
++k;
}
return i == part1.size() && j == part2.size();
}
int main() {
std::string s = "codewars";
std::string part1 = "code";
std::string part2 = "wars";
std::cout << std::boolalpha << is_merge(s, part1, part2) << std::endl; // должно быть true
return 0;
}
```
Этот вариант кода использует три указателя: `i`, `j` и `k`, чтобы просматривать строки `part1`, `part2` и `s` соответственно и убедиться, что символы в `part1` и `part2` появляются в правильном порядке в `s`. Это более надежный способ определить, можно ли объединить `part1` и `part2` для получения `s`.
Попробуйте использовать этот код и проверьте, решит ли он вашу проблему на Codewars.
Что этот код должен, по вашему делать? Я отлично вижу, как он может в этих случаях вернуть false. Если ваш цикл в вашем UNORDERED мапе сначала возьмет самый последний символ сторки part1, то он присвоит переменной order максимально возможное значение и больше ни одино условие в цикле не выполнется - ни один символ больше не удалится.
Разница в поведении компиляторов обусловлена тем, что они по разному мешают этот самый НЕУПОРЯДОЧЕННЫЙ мап. Возможно, там разные хеш функции используются.
И, кстати, ваши multimap-ы тут вообще бесполезны. Во-первых, зачем вам MULTImap, ведь у вас все ключи - это индексы симовлов - уже разные. Во-вторых, зачем вам вообще map, если вы там по каждому индексу храние символ, что итак уже делает строка! У вас тамpart1map[i] == part1[i]всегда. Вместо цикла по мапу, можно пройтись циклом от 0 до длины строки.