2015-08-29 2 views
0

Я пытаюсь найти эффективный алгоритм, который принимает два QAbstractItemModels (деревья) (A, B) и вычисляет различия между ними, так что я получаю список элементов, которые не присутствуют в A (но добавляются в B) или элементы, которые были изменены/удалены.Сравните два QAbstractItemModels

Единственный способ, с помощью которого я могу думать, - это выполнить поиск по ширине A для каждого элемента item в B. Но это не кажется очень эффективным. Любые идеи приветствуются.

+0

Вы должны уточнить свой вопрос. Мне непонятно, что вы подразумеваете под «различиями». Могут быть два вида различий: разница в структуре дерева и разница в значениях узлов. Не ясно, как вы хотите сравнивать узлы (какие данные следует использовать в качестве ключа)? –

+0

Возможно, вы могли бы построить два 'std :: vector ', затем отсортировать их и использовать собственный сопоставитель (который берет данные из соответствующей модели), а затем использовать' std :: set_difference' (также с аналогичным компаратором), чтобы получить разница. Это должно быть O (n log (n)) в отличие от O (n^2). Или, если вы начинаете с пустых деревьев, вы можете сохранить разницу при каждой вставке/удалении на любую из моделей. Но, как сказал @Saz, требуется более подробная информация. – Rostislav

+0

@ Rostislav - это может работать для примитивных значений, но я очень сомневаюсь, что он будет работать для функционального дерева данных. – dtech

ответ

0

Вы пытались использовать магию?

Серьезно, хотя это очень широкий вопрос, особенно если учесть, что это QAbstractItemModels, а не QAbstractListModel. Для списка это будет намного проще, но модель абстрактного элемента реализует древовидную структуру, поэтому существует много переменных.

  • вы проверить общий пункт подсчитывать
  • вы проверяете для пункта подсчитывать на уровень
  • вы проверить, если элемент содержится в обеих моделях
  • , если да, то в нем содержится на тот же уровень
  • если да, то содержится в том же индексе
  • является пунктом в своем первоначальном состоянии или оно было изменено

Вам нужно сделать все эти соображения и придумать эффективное решение. И не ожидайте, что это будет так же просто, как «по алгоритму книги». Хорошая новость, так как вы имеете дело с изолированными элементами, это будет проще, чем пытаться сделать это для текста, а в случае последнего вы не можете надеяться получить почти такую ​​же краткую, как с изолированными элементами. У меня была справедливая доля абсурдно бессмысленных результатов github.

И на всякий случай, это ваша фактическая цель, это будет намного легче достичь, отслеживая историю производных данных, чем делать слепое сравнение. История отслеживания намного проще, если вы хотите установить, что добавлено, что удалено, что перемещено и что изменилось. Потому что он будет рассматривать фактический поток событий, а не только сравнение конечных результатов. Особенно, если у вас нет постоянной схемы ID. Есть ли способ узнать, был ли элемент X удален или перемещен на новый уровень/индекс, а также изменен и т. Д.

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