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

83
20 марта 2021, 20:00

Есть строка 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
Answer 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);
}

Код не проверял, но, думаю, направление вы уловите.

Answer 2

Вот предлагаю по-оптимизировать. Использовать класс QStringRef чтобы лишний раз не копировать строки, и сравнивать хэши:

#include <QVector>
#include <QHash>
template<typename V>
using Hashes = QVector<QPair<uint, V>>;
template<typename V>
Hashes<V> HashItems(const QVector<V> & items)
{
    Hashes<V> result;
    result.reserve(std::size(items));
    for(const auto & i: items)
    {
        result.emplace_back(QHash::qHash(i), i);
    }
    return result;
}
QVector<QStringRef> 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<QStringRef> 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;
}
Answer 3

Предлагаю более простой вариант - воспользоваться QSet, контейнером, предоставляющим быстрый поиск и действия типа пересечения, сложения и вычитания:

QStringList MainWindow::diff(const QString &str1, const QString &str2)
{
    QStringList list1 = str1.split(" ", QString::SkipEmptyParts);
    QStringList list2 = str2.split(" ", QString::SkipEmptyParts);
    QSet<QString> set1 = QSet<QString>::fromList(list1);
    QSet<QString> set2 = QSet<QString>::fromList(list2);
    QSet<QString> d = set2.subtract(set1);
    return QStringList::fromSet(d);
}

На вашем примере

qDebug()<<diff("/dev/sda  /dev/sda1  /dev/sdc  /dev/sdc1", 
               "/dev/sda  /dev/sda1  /dev/sdb  /dev/sdb1 /dev/sdc  /dev/sdc1");

Вывод:

("/dev/sdb1", "/dev/sdb")

UPD

По замечанию @Andrej Levkovitch - этот алгоритм действительно не вполне оптимален, можно его улучшить, например, написав собственный split сразу в QSet и возвращая не QStringList a QSet. Но повторюсь, частота использования этого участка кода и объем данных говорит о том, что скорее всего узким местом в программе он не будет и оптимизировать его преждевременно не стоит.

UPD 2

Не заметил комментария @vegorov под вопросом, мой код в точности реализует его идею вплоть до ответа по поводу скорости работы.

READ ALSO
Как сохранить размер и расположение по центру дочернего изображения при динамически изменяющейся ширине колонки родителя

Как сохранить размер и расположение по центру дочернего изображения при динамически изменяющейся ширине колонки родителя

Вопрос инициирован ответом в топике: Как я могу управлять применением z-index? Hover отменяет z-index до завершения transitions

133
Фильтровать select

Фильтровать select

Есть два select элемента первый это марка авто, второе это модель авто

145
Вставить данные с процедуры в таблицу в MySQL

Вставить данные с процедуры в таблицу в MySQL

Коллеги, кто-то проходил квест по написанию синтаксиса INSERT #Temp EXEC dboTest_Proc @a = @a в MySQL? Это вообще возможно без предварительного создания таблицы...

112