Страницы

Поиск по вопросам

воскресенье, 29 декабря 2019 г.

Вычесть из строки подстроку

#cpp #qt #текст


Есть строка QString DDF1 с n элементами (устройства USB)

Есть строка QString DDF2 с n+1 элементами (добавили флешку)

Нужно получить название этой флешки, но проблема в том, что оно может быть добавлено
в середину текста...

Пример:

Ввод:
/dev/sda  /dev/sda1  /dev/sdc  /dev/sdc1
/dev/sda  /dev/sda1  /dev/sdb  /dev/sdb1 /dev/sdc  /dev/sdc1
Вывод:
/dev/sdb  /dev/sdb1

    


Ответы

Ответ 1



Что-то вроде того: QString str1{"/dev/sda /dev/sda1 /dev/sdc /dev/sdc1"}; QString str2 { "/dev/sda /dev/sda1 /dev/sdb /dev/sdb1 /dev/sdc /dev/sdc1" } auto list1 = str1.split(" "); auto list2 = str2.split(" "); list1.sort(); list2.sort(); QStringList retval{}; auto secondIter = list1.begin(); for (auto i = list2.begin(); i != list2.end;) { if (secondIter == list1.end()) { retval.push_back(*i); ++i; } else { if (*i != *secondIter) { retval.push_back(*secondIter); ++secondIter; } } } for (; secondIter != list1.end(); ++secondIter) { retval.push_back(*secondIter); } Код не проверял, но, думаю, направление вы уловите.

Ответ 2



Вот предлагаю по-оптимизировать. Использовать класс QStringRef чтобы лишний раз не копировать строки, и сравнивать хэши: #include #include template using Hashes = QVector>; template Hashes HashItems(const QVector & items) { Hashes result; result.reserve(std::size(items)); for(const auto & i: items) { result.emplace_back(QHash::qHash(i), i); } return result; } QVector diff(const QString & str1, const QString & str2) { auto tokens1 = HashItems(str1.splitRef(" ")); auto tokens2 = HashItems(str2.splitRef(" ")); // оптимизация, из короткого удалять дешевле const auto & large = std::size(tokens1) > std::size(tokens2) ? tokens1 : tokens2; auto & small = std::size(tokens1) <= std::size(tokens2) ? tokens1 : tokens2; QVector result; for(const auto & l : large) { bool unique = true; for(auto s = std::begin(small); s != std::end(small);) { if(l.first != s->first) { ++s; } else { unique = false; s = small.erase(s); } } if(unique) { result.push_back(l.second); } } for(const auto & s: small) { result.push_back(s.second); } return result; }

Ответ 3



Предлагаю более простой вариант - воспользоваться QSet, контейнером, предоставляющим быстрый поиск и действия типа пересечения, сложения и вычитания: QStringList MainWindow::diff(const QString &str1, const QString &str2) { QStringList list1 = str1.split(" ", QString::SkipEmptyParts); QStringList list2 = str2.split(" ", QString::SkipEmptyParts); QSet set1 = QSet::fromList(list1); QSet set2 = QSet::fromList(list2); QSet d = set2.subtract(set1); return QStringList::fromSet(d); } На вашем примере qDebug()<

Комментариев нет:

Отправить комментарий