#c
#c
Вопрос:
Итак, у меня есть два объекта, которые содержат вектор файловых объектов, называемых files (которые могут содержать либо файл, либо файл каталога, а также все файлы, на которые он указывает). Если я сделаю что-то вроде B2 -= B1, я хочу, чтобы он удалил все, что есть в B1, из B2, если это применимо. Я сравниваю, совпадают ли файловые объекты, проверяя их ino_t inode и dev_t devicenumber .
В настоящее время это мой код
Someclassamp; Someclass::operator-=(const Someclass amp;rhs){
vector<AnotherClass> retfiles;
for (auto i = 0; i < static_cast<int>(files.size()); i ){
for (auto j = 0; j < static_cast<int (rhs.files.size()); j ){
if (i < j){
if (!isSameFile(files.at(i), rhs.files.at(i))){
retfiles.push_back(files.at(i));
}
}
}
files = retfiles;
return *this;
}
bool Someclass::isSameFile(const AnotherClass amp;lhs, const AnotherClass amp;rhs) {
return (lhs.getInode() == rhs.getInode()) amp;amp; (lhs.getDeviceNumber() == rhs.getDeviceNumber());
}
Моя проблема в том, что я не могу правильно удалить файлы с левой стороны (в случае, если объект rhs может содержать больше файлов, чем объект lhs) или в случае удаления дубликатов из моего вектора.
SomeClass 1:
-rw-r--r-- pub/tree/alpha/iota/omega
-r--r--r-- pub/tree/alpha/iota/kappa
drwxr-xr-x pub/tree/alpha/iota
SomeClass 2:
-rw-r--r-- pub/tree2/tau/sigma
drwxr-xr-x pub/tree2/tau
-rw-r--r-- /etc/group
SomeClass 3:
Когда SomeClass3-=SomeClass2
должно выглядеть так
-rw-r--r-- pub/tree/alpha/iota/omega
-r--r--r-- pub/tree/alpha/iota/kappa
drwxr-xr-x pub/tree/alpha/iota
Комментарии:
1. самые внутренние тела if и else идентичны, может ли это быть источником ваших проблем?
2. Как уже упоминалось, ваше это не имеет никакого эффекта, также вы добавляете кратные значения, поскольку при каждом сравнении вы добавляете, если это не совпадает. Скорее просмотрите весь список и посмотрите, есть ли совпадение, и только тогда определите, что делать
3. Думаю, я бы сказал, что я немного запутался в этом, поэтому, удалив это else во внутреннем цикле, теперь я просто ничего не добавляю в Vector<AnotherClass> retfile .
4. Почему вы проверяете
if (i < j)
? Кроме этого, вы никогда не используетеj
внутри своего цикла.5. В случае, если вектор rhs содержит больше файлов, чем аргумент lhs, поэтому я не выхожу за пределы.
Ответ №1:
Поиск элементов из массива, которые не существуют в другом массиве, называется set difference, и в стандартной библиотеке есть функция, которая может это сделать.
vector<AnotherClass> retfiles;
std::set_difference(files.begin(), files.end(),
rhs.files.begin(), rhs.files.end(),
std::back_inserter(retfiles), isSameFile);
// retfiles contains elements from files that didn't exists in rhs.files
Вам понадобится #include <algorithm>
для set_difference и #include <iterator>
для back_inserter .
Редактировать:
На самом деле isSameFile
не совсем то, что нужно set_difference. Вам нужно будет использовать функцию сравнения для сортировки массивов и использовать ту же функцию для set_difference .
В вашем комментарии ниже cmp
это будет нормально, если getDeviceNumber
это единственное, что отличает файлы, но я вижу, что у вас getInode
тоже есть. Поэтому вы можете захотеть создать функцию сравнения, подобную этой:
bool cmp(const Fing amp;lhs, const Fing amp;rhs) { // typo?
if (lhs.getDeviceNumber() != rhs.getDeviceNumber())
return lhs.getDeviceNumber() < rhs.getDeviceNumber();
else
return lhs.getInode() < rhs.getInode();
}
и используйте это для сортировки и перехода к set_difference.
Комментарии:
1. Спасибо! Будет ли это по-прежнему работать в случае, если я попытаюсь сделать это на том же объекте? Например, SomeClass a1 -= SomeClass a2? В этом случае он вернет пустой массив?
2. Не
std::set_difference
требует сортировки входных данных?3. @Thegreatfoo да,
retfiles
будет пустым, еслиfiles
иrhs.files
идентичны4. @kmdreko
bool cmp(const Fing amp;lhs, const Fing amp;rhs){ return lhs.getDeviceNumber() < rhs.getDeviceNumber(); }
У меня есть метод, смогу ли я включить это, чтобы отсортировать файлы перед использованием set_difference?5. @Thegreatfoo неопределенные ссылочные ошибки? это странно … это может произойти, если ваша программа не создается должным образом или если функция используется, но не определена…