c++11 - intersection of n vectors -


i'm new programming , i've come across issue finding intersection of n vectors, (int vectors) have sorted ints. approach came has complexity of o(n^2) , using std::set_intersect function.

the approach came having 2 vectors: first vector correspond first vector have, , second second vector. call set intersection on 2 , overwrite first vector, use vector clear function on second. overwrite next vector second, , repeat process, , returning first vector.

i believe there more efficient way of going this, @ moment, can not think of more efficient manner. on issue appreciated.

fortunately, think tighter bound can placed on complexity of algorithm.

the complexity of std::set_intersection on input sets of size n1 , n2 o(n1 + n2). take original vectors , intersect them in single-elimination tournament style, is, on first round intersect 1st , 2nd vectors, 3rd , 4th, 5th , 6th, , forth; on second round intersect 1st , 2nd intersections, 3rd , 4th, , forth; repeat until final round produces 1 intersection. sum of sizes of vectors surviving each round no more half sum of sizes of vectors @ start of round, algorithm takes o(n) time (also o(n) space) altogether n sum of sizes of original vectors in input. (it's o(n) because n + n/2 + n/4 + ... < 2n.)

so, given input consisting of already-sorted vectors, complexity of algorithm o(n).

your algorithm merges vectors in different sequence, while i'm not 100% sure o(n), suspect is.


edit: concerning how implement "tournament" algorithm in c++, depends on how hard want work optimize this, , on nature of input.

the easiest approach make new list of vectors; take 2 vectors old list, push vector onto new list, merge 2 old vectors onto new vector, destroy old vectors, hope library manages memory efficiently.

if want reduce allocation of new vectors, re-using vectors (as thought do) might help. if input data structure std::list<std::vector<int> >, example, start pushing 1 empty vector onto front of list. make 3 iterators, 1 new vector, , 1 each of original first 2 vectors in list. take intersection of vectors @ last 2 iterators, writing result first iterator, clear vectors @ last 2 iterators. move last 2 iterators forward 2 places each, move first iterator forward 1 place. repeat. if reach state 1 of last 2 iterators has reached end() other has not, erase list elements between first iterator , other iterator. have list of vectors again , can repeat long there more 1 vector in list.

if input std::vector<std::vector<int> > pushing element onto front of list relatively expensive, might want more complicated algorithm. there lots of choices, no obvious winners can think of.


Comments

Popular posts from this blog

google chrome - Developer tools - How to inspect the elements which are added momentarily (by JQuery)? -

angularjs - Showing an empty as first option in select tag -

php - Cloud9 cloud IDE and CakePHP -