Что вообще делает std :: include?
Из стандарта std::includes
:
Возвращает: true
если [first2, last2)
пуст или каждый элемент в диапазоне [first2, last2)
содержится в диапазоне [first1, last1)
. Возвращает false
противном случае.
Примечание: поскольку это находится под [alg.set.operations], диапазоны должны быть отсортированы
Принимая это буквально, если мы допустим R1=[first1, last1)
и R2=[first2, last2)
, это оценивает:
∀a∈R2 a∈R1
Однако это не то, что на самом деле оценивается. Для R1={1}
и R2={1,1,1}
, std::includes(R1, R2)
возвращает false:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>
int main() {
std::vector<int> a({1});
std::vector<int> b({1,1,1});
// Outputs 'false'
std::cout << std::boolalpha
<< std::includes(a.begin(), a.end(), b.begin(), b.end()) << '\n';
}
Live на Wandbox
Это удивительно. Я проверил его как с libstdc++, так и с libc++, но мне кажется маловероятным, что это будет ошибкой в реализации стандартной библиотеки, считая его частью библиотеки алгоритмов. Если это не алгоритм, который должен запускать std::includes
, что это такое?
Ответы
Ответ 1
Я отправил это в cpplang slack, и Кейси Картер ответил:
Описание алгоритма в стандарте является дефектным. Цель состоит в том, чтобы определить [если] каждый элемент в игле появляется в порядке в стоге сена.
[Алгоритм, который он фактически выполняет:] "Возвращает true, если пересечение отсортированных последовательностей R1 и R2 равно R2"
Или, если мы гарантируем, что мы уверены в значении подпоследовательности:
Возвращает: истинно тогда и только тогда, когда [first2, last2] является подпоследовательностью [first1, last1)
ссылка на сообщение Кейси Картера
Ответ 2
Я считаю, что вы пытаетесь проверить, если включает a
b
в вашем примере, не включает в себя a
b
а b
действительно включает. a
Если вы поменяете b
и a
он вернет true, так как a
включен в b
.
Надеюсь, я не пропущу что-то очевидное.
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> a({1});
std::vector<int> b({1,1,1});
// Outputs 'true'
std::cout << std::boolalpha
<< std::includes(b.begin(), b.end(), a.begin(), a.end()) << '\n';
}
То, что я понял, играя с алгоритмом, заключается в том, что когда вы вводите includes(R2, R1)
он проверяет, владеет ли R2
собственностью R1
в качестве подгруппы, если yes возвращает true
если не возвращает false
. Также, если он не заказал ошибку, то sequence not ordered
.
Ответ 3
Как всегда при чтении стандарта, вы должны прочитать неписаные слова.
Сосредоточьтесь на намерении не только на букве. (Формулировка стандарта часто считалась неопределенной, неполной, самореферентной или противоречивой.)
Прочтите введение раздела " 28.7.6. Установите операции над отсортированными структурами [alg.set.operations] ":
В этом подпункте определяются все операции базового набора в отсортированных структурах. Они также работают с мультимножествами, содержащими несколько копий эквивалентных элементов. Семантика заданных операций обобщается на мультимножества стандартным образом, определяя set_union(), чтобы содержать максимальное количество вхождений каждого элемента, set_intersection(), чтобы содержать минимум, и так далее.
Поэтому совершенно ясно, что слова в описании includes
:
Возвращает: true, если [first2, last2] пуст или каждый элемент в диапазоне [first2, last2] содержится в диапазоне [first1, last1]. Возвращает false в противном случае.
должны быть проигнорированы. Вам нужно знать априори, какие мультимножества выполняются, что означает "включает" средства для двух мультимножеств, игнорировать описание и перестраивать в голове, что было очевидным намерением.
Множественное включение:
A входит в B, если объединение A B = B.
Это справедливо для множеств или мультимножеств.