Форум » C/C++ для начинающих (C/C++ for beginners) » ID based 2d data replacing » Ответить

ID based 2d data replacing

ramees: i have 2d vector data like this ID, data, data , data 1 , 125 , 458 , 1245 2 , 145 , 448 , 1245 1 , 455 , 489 , 1785 6 , 142 , 458 , 1245 2 , 125 , 458 , 1545 1 , 685 , 758 , 7525 6 , 142 , 458 , 1245 you can see the ID value that in red color i like to replace same id data with its first id data for example ID, data, data , data 1 , 125 , 458 , 1245 2 , 145 , 448 , 1245 1 , 125 , 458 , 1245 6 , 142 , 458 , 1245 2 , 145 , 448 , 1245 1 , 125 , 458 , 1245 6 , 142 , 458 , 1245 i try to code this in using vector & pair but its a big fail i need help

Ответов - 6

Сыроежка: Please show how the vector is defined. Is it an object of type std::vector<std::vector<int>> or a two-dimensional array or something else? For example if the vector has indeed type std::vector<std::vector<int>> and there are many repeating IDs then the code can look the following way [pre2] #include <iostream> #include <vector> #include <map> int main() { std::vector<std::vector<int>> v = { { 1 , 125 , 458 , 1245 }, { 2 , 145 , 448 , 1245 }, { 1 , 455 , 489 , 1785 }, { 6 , 142 , 458 , 1245 }, { 2 , 125 , 458 , 1545 }, { 1 , 685 , 758 , 7525 }, { 6 , 142 , 458 , 1245 } }; for ( const auto &v1 : v ) { for ( int x : v1 ) std::cout << x << ' '; std::cout << std::endl; } std::cout << std::endl; std::map<int, std::vector<std::vector<int>>::iterator> m; for ( auto it = v.begin(); it != v.end(); ++it ) { if ( !it->empty() ) { auto p = m.find( ( *it )[0] ); if ( p != m.end() ) { *it = *p->second; } else { m[( *it )[0]] = it; } } } for ( const auto &v1 : v ) { for ( int x : v1 ) std::cout << x << ' '; std::cout << std::endl; } std::cout << std::endl; return 0; } [/pre2] The output is [pre2] 1 125 458 1245 2 145 448 1245 1 455 489 1785 6 142 458 1245 2 125 458 1545 1 685 758 7525 6 142 458 1245 1 125 458 1245 2 145 448 1245 1 125 458 1245 6 142 458 1245 2 145 448 1245 1 125 458 1245 6 142 458 1245 [/pre2] The code was compiled at www.ideone.com.

ramees: yes exactly what i want . thanks

ramees: what is this -> arrow mark means . how its working in if ( !it->empty() ) and *it = *p->second;


Сыроежка: Iterators look as pointers that is they overload operators -> and *. In the code above iterator it "points" to an internal vector and this expression it->empty() checks whether the vector is empty. If it is empty then nothing is done. A dereferenced iterator gives a reference to the object it points to. So in this statement *it = *p-second; there is copied the vector pointed to by p->second to the vector pointed to by it. Take into account that the value_type is defined for class std::map the following way typedef pair<const Key, T> value_type; You can use another approach that sequentially checks whether there is already an element with the same ID and copies the existent element in the target element. In this case the complexity will be O( n^2 ) but neither additional memory will be allocated. For example [pre2] #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<std::vector<int>> v = { { 1 , 125 , 458 , 1245 }, { 2 , 145 , 448 , 1245 }, { 1 , 455 , 489 , 1785 }, { 6 , 142 , 458 , 1245 }, { 2 , 125 , 458 , 1545 }, { 1 , 685 , 758 , 7525 }, { 6 , 142 , 458 , 1245 } }; for ( const auto &v1 : v ) { for ( int x : v1 ) std::cout << x << ' '; std::cout << std::endl; } std::cout << std::endl; for ( auto it = v.begin(); it != v.end(); ++it ) { if ( !it->empty() ) { auto it1 = std::find_if( v.begin(), it, [&]( const std::vector<int> &v1 ) { return !v1.empty() && v1.front() == it->front(); } ); if ( it1 != it ) { *it = *it1; } } } for ( const auto &v1 : v ) { for ( int x : v1 ) std::cout << x << ' '; std::cout << std::endl; } std::cout << std::endl; return 0; } [/pre2] The output is [pre2] 1 125 458 1245 2 145 448 1245 1 455 489 1785 6 142 458 1245 2 125 458 1545 1 685 758 7525 6 142 458 1245 1 125 458 1245 2 145 448 1245 1 125 458 1245 6 142 458 1245 2 145 448 1245 1 125 458 1245 6 142 458 1245 [/pre2]

Сыроежка: ramees, by mistake I deleted your post instead of deleting my post that I wanted to rewrite and do not know how to restore it. I am sorry. Nevertheless we can continue the discussion. In the deleted by mistake your post you asked to review your code. Here is your code [pre2] #include <iostream> #include <vector> #include <map> #include <algorithm> int main() { float A[][6]={ { 2 , 125 , 458 , 1245 }, { 1 , 125 , 456 , 1245 }, { 1 , 125 , 756 , 1245 }, { 6 , 455 , 489 , 6785 }, { 2 , 125 , 458 , 1545 }, { 1 , 525 , 458 , 1545 }, { 6 , 142 , 458 , 1245 } }; std::vector<std::vector<float>> v; std::vector<std::vector<float>> b; for(int i = 0; i < 7;i++){ std::vector<float> _A; std::vector<float> _B; v.push_back(_A); b.push_back(_B); for(int j = 0 ; j < 4;j++){ v[i ] .push_back(A[ i ][ j ]); b[ i ].push_back(A[ i ][ j ]); } } for ( auto it = v.begin(); it != v.end(); ++it ) { if ( !it->empty() ) { auto it1 = std::find_if( v.begin(), it, [&]( const std::vector<float> &v1 ) { return !v1.empty() && v1.at(1) != it->at(1) && v1.at(2) == it->at(2) && v1.at(3) == it->at(3) || v1.at(1) == it->at(1) && v1.at(2) != it->at(2) && v1.at(3) == it->at(3) || v1.at(1) == it->at(1) && v1.at(2) == it->at(2) && v1.at(3) != it->at(3) ; } ); if ( it1 != it ) { if(it1->at(1) != it->at(1) && it1->at(2) == it->at(2) && it1->at(3) == it->at(3)){ it->at(1)= it1->at(1); }else if(it1->at(1) == it->at(1) && it1->at(2) != it->at(2) && it1->at(3) == it->at(3)){ it->at(2)= it1->at(2); }else if(it1->at(1) == it->at(1) && it1->at(2) == it->at(2) && it1->at(3) != it->at(3)){ it->at(3)= it1->at(3); } } } } for each ( const std::vector<float> &v1 in v ) { for each ( float x in v1 ) std::cout << x << ' '; std::cout << std::endl; } return 0; } [/pre2] And here is my review. Use tag pre2 to enclose in it a program text that to preserve its formating. As for your code then it is a bad udea to use identifiers that start from underscore because such names usually reserved by the implementation. Also names of variables should not consist from capital letters. Try not to use magic numbers. Vector b is defined but never used in the program. The filling of vector v can be written simpler [pre2] #include <iostream> #include <vector> #include <iterator> int main() { const size_t N = 6; float a[][N] = { { 2 , 125 , 458 , 1245 }, { 1 , 125 , 456 , 1245 }, { 1 , 125 , 756 , 1245 }, { 6 , 455 , 489 , 6785 }, { 2 , 125 , 458 , 1545 }, { 1 , 525 , 458 , 1545 }, { 6 , 142 , 458 , 1245 } }; std::vector<std::vector<float>> v; v.reserve( sizeof( a ) / sizeof( *a ) ); for ( const auto &row : a ) { v.push_back( std::vector<float>( std::begin( row ), std::next( std::begin( row ), 4 ) ) ); } //...; } [/pre2] In the find algorithm if you are accessing elements with index 3 then instead of condition !v1.empty() you have to use condition v1.size() >= 4 The condition itself looks wrong. it has to be written as [pre2] v1.size() >= 4 && ( v1.at(1) != it->at(1) && v1.at(2) == it->at(2) && v1.at(3) == it->at(3) || v1.at(1) == it->at(1) && v1.at(2) != it->at(2) && v1.at(3) == it->at(3) || v1.at(1) == it->at(1) && v1.at(2) == it->at(2) && v1.at(3) != it->at(3) ) [/pre2] That is you have to enclose all comparisons in parentheses. Also are you sure that the first compared element should have index 1 instead of index 0?

ramees: yes i am sure the first compared element should have index 1 instead of index 0 because index 0 is ID value. i don't want to compare ID thank u for reviewing code and pointing my mistakes i will try not to make same again



полная версия страницы