There is an array masiv_C0 = {{A, B}, {A, C}, {B, C}}

There is an array masiv_X0 = {{A, B}}

It is necessary to create the third array of the first two:

masiv_Y1 = masiv_C0 - masiv_X0 = {{A, C}, {B, C}}

The problem is that in the third array that I create, separate elements A and B are also deleted.

As a result, instead of getting {{A, C}, {B, C}} I get {{C}, {C}} ... Help me fix the code! Thanks in advance :)

 #include <iostream> #include <vector> #include <algorithm> #include <iterator> using namespace std; typedef std::vector<std::string> String1D; typedef std::vector<String1D> String2D; int main() { String2D masiv_C0(3, String1D(2)); masiv_C0[0][0]="A"; masiv_C0[0][1]="B"; masiv_C0[1][0]="A"; masiv_C0[1][1]="C"; masiv_C0[2][0]="B"; masiv_C0[2][1]="C"; String2D masiv_X0(1, String1D(2)); masiv_X0[0][0]="A"; masiv_X0[0][1]="B"; String2D masiv_Y1 = masiv_C0; for ( size_t i = 0; i < masiv_X0.size(); ++i) { for ( size_t j = 0; j < masiv_X0[i].size(); ++j) { auto& str = masiv_X0[i][j]; for (size_t cur = 0; cur < masiv_Y1.size(); ++cur) { auto iter = std::remove(masiv_Y1[cur].begin(), masiv_Y1[cur].end(), str); masiv_Y1[cur].erase(iter, masiv_Y1[cur].end()); } } } String2D::iterator iter = masiv_Y1.begin(); while (iter != masiv_Y1.end()) { std::copy((*iter).begin(), (*iter).end(), std::ostream_iterator<std::string>(cout, " ")); cout << "\n"; ++iter; } return 0; } 

    3 answers 3

    If each element of the external vector contains a vector of two elements, then it is more reasonable to replace the internal vector of two elements with an object of type std::pair<std::string, std::string> . In this case, the code will be more understandable. Also, instead of the usual for loops, it is easier to use range-based loops.

    The program may look like this. I kept the names of the vectors the same as you use.

     #include <iostream> #include <vector> #include <string> #include <utility> #include <algorithm> int main() { std::vector<std::pair<std::string, std::string>> masiv_C0 = { { "AB", "ADF" }, { "BC", "ADF" }, { "CD", "BC" }, { "DE", "ADF" } }; for ( const std::pair<std::string, std::string> &p : masiv_C0 ) { std::cout << "{ " << p.first << ", " << p.second << " } "; } std::cout << std::endl; std::vector<std::pair<std::string, std::string>> masiv_X0 = { { "AB", "ADF" }, { "CD", "BC" }, { "DE", "ADF" } }; for ( const std::pair<std::string, std::string> &p : masiv_X0 ) { std::cout << "{ " << p.first << ", " << p.second << " } "; } std::cout << std::endl; std::vector<std::pair<std::string, std::string>> masiv_Y1 = masiv_C0; for ( const std::pair<std::string, std::string> &p : masiv_X0 ) { masiv_Y1.erase( std::remove( masiv_Y1.begin(), masiv_Y1.end(), p ), masiv_Y1.end() ); } for ( const std::pair<std::string, std::string> &p : masiv_Y1 ) { std::cout << "{ " << p.first << ", " << p.second << " } "; } std::cout << std::endl; return 0; } 

    Program output

     { AB, ADF } { BC, ADF } { CD, BC } { DE, ADF } { AB, ADF } { CD, BC } { DE, ADF } { BC, ADF } 
       #include <iostream> #include <vector> #include <algorithm> #include <iterator> using namespace std; typedef std::vector<std::string> String1D; typedef std::vector<String1D> String2D; int main() { /* // это "мишени" String2D masiv_C0(3, String1D(2)); masiv_C0[0][0]="A"; masiv_C0[0][1]="B"; masiv_C0[1][0]="A"; masiv_C0[1][1]="C"; masiv_C0[2][0]="B"; masiv_C0[2][1]="C"; // а это "образцы" String2D masiv_X0(1, String1D(2)); masiv_X0[0][0]="A"; masiv_X0[0][1]="B"; */ // это "мишени" String2D masiv_C0(4, String1D(2)); masiv_C0[0][0]="AB"; masiv_C0[0][1]="ADF"; masiv_C0[1][0]="BC"; masiv_C0[1][1]="ADF"; masiv_C0[2][0]="CD"; masiv_C0[2][1]="BC"; masiv_C0[3][0]="DE"; masiv_C0[3][1]="ADF"; // а это "образцы" String2D masiv_X0(3, String1D(2)); masiv_X0[0][0]="AB"; masiv_X0[0][1]="ADF"; masiv_X0[1][0]="CD"; masiv_X0[1][1]="BC"; masiv_X0[2][0]="DE"; masiv_X0[2][1]="ADF"; String2D masiv_Y1 = masiv_C0; // цикл по образцам for (int i = 0; i < masiv_X0.size(); ++i) { // цикл по мишеням //// идём с конца, чтобы при удалени не нарушать порядок //// в итоге получается -1, поэтому счётчик знаковый for (int j = masiv_C0.size() - 1; j >= 0; --j) { // нужно ли удалять мишень bool todel = true; // цикл по символам for (int sym = 0; sym < masiv_X0[i].size(); ++sym) { // если хоть один символ не совпал if (masiv_X0[i][sym] != masiv_C0[j][sym]) { // удалять не надо todel = false; break; } } // если нужно удалить мишень if (todel) { masiv_Y1.erase(masiv_Y1.begin() + j); } } } String2D::iterator iter = masiv_Y1.begin(); // вывод while (iter != masiv_Y1.end()) { std::copy((*iter).begin(), (*iter).end(), std::ostream_iterator<std::string>(cout, " ")); cout << "\n"; ++iter; } return 0; } 

      Conclusion:

       AC BC 
      • @ Merk30 is exactly that, my solution works as it should. I tend to copy it clumsily. Input updated. I tested here: tutorialspoint.com/compile_cpp11_online.php - AivanF.
      • I apologize, but look at the following data, I received them when processing the graph and your algorithm does not quite correctly process them - Merk30
      • In the new array should be and ( {CF, B}; {E, E} ) instead of them there are superfluous ( {C, BС}; {D, ADF} ) I am glad that your algorithm is suitable for other values, but my graph is processes incorrectly :( - Merk30

      Following the traces of Vlad from Moscow , i.e. using STL - it seems to me easier to use sets and set_difference :

       #include <iostream> #include <vector> #include <string> #include <utility> #include <algorithm> #include <set> #include <iterator> using Data = std::pair<std::string, std::string>; using namespace std; int main() { set<Data> masiv_C0 = { { "AB", "ADF" }, { "BC", "ADF" }, { "CD", "BC" }, { "DE", "ADF" } }; for ( auto p : masiv_C0 ) { cout << "{ " << p.first << ", " << p.second << " } "; } cout << endl; set<Data> masiv_X0 = { { "AB", "ADF" }, { "CD", "BC" }, { "DE", "ADF" } }; for ( auto p : masiv_X0 ) { cout << "{ " << p.first << ", " << p.second << " } "; } cout << endl; set<Data> masiv_Y1; set_difference(masiv_C0.begin(),masiv_C0.end(), masiv_X0.begin(),masiv_X0.end(), inserter(masiv_Y1,masiv_Y1.end())); for (auto p : masiv_Y1 ) { cout << "{ " << p.first << ", " << p.second << " } "; } cout << endl; return 0; } 

      You can and vector, but then they must be sorted before finding the difference.

      • These are not equivalent solutions. std :: set_difference does not remove all matching elements in the source vectors. For example, if the source vectors have elements {1, 1, 2} and {1}, then the resulting vector will be {1, 2} instead of {2} ... - Vlad from Moscow