It is necessary to combine two arrays into the third one so that the elements that are repeated in both arrays are not added, i.e. a = {1,2,3} b = {3,4,5} -> c = {1,2,3,4,5}.

He made many ingenious designs - none worked normally. Please help.

cout << "step1" << endl; for (i = 0;i < MainCobj->n; i++) { MainCobj->c[i] = MainCobj->a[i]; } cout << "step2" << endl; itemp = MainCobj->n; for (j = 0;j < MainCobj->m;j++) { for (k = 0;k, MainCobj->n;k++) { if (MainCobj->b[i] == MainCobj->a[k]) { continue; } else { MainCobj->c[itemp] = MainCobj->b[i]; } itemp++; } } 

All elements with А go to С Further 2 cycles, if there is a match, the element is not added. itemp is a counter С array.

  • one
    What specific "constructions" did not work - show. And tell in your own words the algorithms of their work. - PinkTux
  • 'cout << "step1" << endl; for (i = 0; i <MainCobj-> n; i ++) {MainCobj-> c [i] = MainCobj-> a [i]; } cout << "step2" << endl; itemp = MainCobj-> n; for (j = 0; j <MainCobj-> m; j ++) {for (k = 0; k, MainCobj-> n; k ++) {if (MainCobj-> b [i] == MainCobj-> a [k] ) {continue; } else {MainCobj-> c [itemp] = MainCobj-> b [i]; } itemp ++; }} 'All elements with A go to C. Next 2 cycles, if there is a match, the element is not added. itemp is a counter from an array. - Sashkov Kovalchuk 4:34 pm
  • look here at stackoverflow.com/questions/19719337/… and here stackoverflow.com/questions/12791266/… related topics and a possible solution - Duracell
  • one
    I would in general set everything back and set back ... Well, or 2 pointers if the elements are sorted. - pavel
  • An example you have in the question uses integers, and the header refers to "string" arrays - jfs

2 answers 2

The condition can be interpreted in two ways. If the task is for all the elements to be unique, it is convenient to use std::set or std::unordered_set :

 #include <algorithm> // copy() #include <iostream> // cout #include <iterator> // ostream_iterator<> #include <set> #define SIZE(array) (sizeof(array) / sizeof(*array)) int main() { typedef int Value; Value a[] = {3,2,1,1,2,3}, b[] = {3,3,3,4,5,5}; std::set<Value> c(a, a + SIZE(a)); c.insert(b, b + SIZE(b)); std::copy(c.begin(), c.end(), std::ostream_iterator<Value>(std::cout, " ")); } 

The complexity of the creation is linear-logarithmic: O(n*log n + m*log m) , where n , m dimensions a and b . You can make the creation time linear using unordered_set , if the Value type allows.

Example:

 $ g++ merge_all_unique.cc && ./a.out 1 2 3 4 5 

You can see that the result is sorted and there are no duplicate items.

If inside a and b elements can be repeated, but you cannot just add elements from b that already exist in a :

 #include <algorithm> // copy() #include <iostream> // cout #include <iterator> // ostream_iterator<>, begin(), end() #include <unordered_set> #include <vector> int main() { using std::begin; using std::end; typedef int Value; Value a[] = {3,2,1,1,2,3}, b[] = {3,3,3,4,5,5}; std::vector<Value> c(begin(a), end(a)); std::unordered_set<Value> a_set(begin(c), end(c)); std::copy_if(begin(b), end(b), std::back_inserter(c), [&a_set] (Value item) { return a_set.find(item) == a_set.end(); // item not in a }); std::copy(begin(c), end(c), std::ostream_iterator<Value>(std::cout, " ")); } 

The complexity of creating c linear: O(n + m) .

Example:

 $ g++ -std=c++11 merge_not_in_a.cc && ./a.out 3 2 1 1 2 3 4 5 5 

It can be seen that the elements are not sorted and can be repeated (how many times they are present in separate input arrays). 3 not copied from b , because this number is already in a .

To taste, instead of algorithms, you can use explicit loops:

 #include <iostream> // cout #include <iterator> // begin() #include <unordered_set> #include <vector> int main() { typedef int Value; Value a[] = {3,2,1,1,2,3}, b[] = {3,3,3,4,5,5}; std::vector<Value> c(std::begin(a), std::end(a)); std::unordered_set<Value> a_set(c.begin(), c.end()); for (auto item : b) { if (a_set.find(item) == a_set.end()) { // if not in `a` c.push_back(item); // copy from `b` } } for (auto item : c) { std::cout << item << ' '; } } 

The result and execution time are the same.

    Will work with many containers and even with regular arrays.

     #include <windows.h> #include <array> #include <algorithm> int main() { std::array<int, 10> arr1 = { 1,2,3,4,5 }; std::array<int, 5> arr2 = { 1,7,8,9,5 }; std::copy_if(arr2.begin(), arr2.end(), arr1.begin() + 5, [&](const int& _1) {for (auto it : arr1) { if (it == _1)return false; }return true; }); for (auto it : arr1) { printf_s("%d\n", it); } while (true) { Sleep(1); } return 0; } 
    • You should not use quadratic algorithms if the linear algorithm is also easy to implement. - jfs
    • @jfs is it possible in more detail, is it linear with unordered_set ? or provided that both arrays are already sorted? - pavel
    • @pavel replace the word set with unordered_set in the code and that's it. Sorting elements does not require this, only that the Value type can be hashed ( std::hash<> , std::equal_to<> ). - jfs
    • @jfs yes I understand. It's just that the unordered_set has a bad feature, that sometimes it works slower than usual. At olympiadadh sometimes climbed very sideways. - pavel
    • @pavel imagine input has a million items, then your code requires ~ 10**12 operations compared ~ 10**6 for unordered_set . For the code in my answer, the delays that you mention are not applicable (only to read operations after they are created), but in general, an individual operation with unordered_set can really take an unexpectedly long time (if you need to rearrange the bouquets), but on average this is amortized. Another option is possible with malicious input for some implementations (it may be relevant for web servers), but even this is not worse than a quadratic algorithm. - jfs