template<class T> bool sequence_is_sorted(const T& seq, bool decreasing=false) { typename T::const_iterator i; if (decreasing) { //if no value is less than its successor, it is decreasingly sorted i = adjacent_find(seq.begin(), seq.end(), std::less<typename T::value_type>()); } else { //increasing i = adjacent_find(seq.begin(), seq.end(), std::greater<typename T::value_type>()); } return (i == seq.end()); }
void pure_numeric_algo(){ cout<<endl<<"pure_numeric_algo :"<<endl; int ia[11] = {0, 1, 2, 3, 4, 5, 6,6,6, 7, 8 }; vector<int> iv(ia,ia+11); vector<int> iv2(ia+6,ia+8); vector<int>::iterator itr; itr = adjacent_find(iv.begin(),iv.end(), equal_to<int>()); //找到相邻元素相等的第一个元素 cout<<"adjacent_find: "<<*itr<<endl; cout<<"count: "<<count(iv.begin(),iv.end(), 6)<<endl; //找到元素值等于6的个数 cout<<"count_if: "<<count_if(iv.begin(),iv.end(), bind2nd(less<int>() , 7))<<endl; //找到小于7的元素个数 itr = find(iv.begin(),iv.end(), 4); //找到元素等于4的第一个元素位置 cout<<"find: "<<*itr<<endl; itr = find_if(iv.begin(),iv.end(), bind2nd(greater<int>() , 2)); //找到元素大于2的第一个元素位置 cout<<"find_if: "<<*itr<<endl; itr = find_end(iv.begin(),iv.end(), iv2.begin(),iv2.end()); //找到iv序列中最后子序列匹配出现的位置 cout<<"find_end: "<<*(itr+3)<<endl; itr = find_first_of(iv.begin(),iv.end(), iv2.begin(),iv2.end()); //找到iv序列中最先子序列匹配出现的位置 cout<<"find_end: "<<*(itr+3)<<endl; remove(iv.begin(),iv.end(), 6); //删除元素,向前移,但是容器size不变,后面会剩余数据 cout<<"remove: "<<iv<<endl; vector<int> iv3(12,-1); remove_copy(iv.begin(),iv.end(), iv3.begin(), 6); //删除元素,将数据拷贝到新容器,后面会剩余数据 cout<<"remove_copy: "<<iv3<<endl; remove_if(iv.begin(),iv.end(), bind2nd(less<int>(), 6)); //删除小于6的元素,后面会剩余数据 cout<<"remove_if: "<<iv<<endl; remove_copy_if(iv.begin(),iv.end(), iv3.begin(), bind2nd(less<int>(), 7)); //删除小于7的元素,并拷贝到新容器 cout<<"remove_copy_if: "<<iv3<<endl; replace(iv.begin(),iv.end(), 6, 3); //将所有元素值为6的改为3 cout<<"replace: "<<iv<<endl; replace_copy(iv.begin(),iv.end(),iv3.begin(), 3, 5); //将所有元素值为3的改为5,结果保存在新容器中 cout<<"replace_copy: "<<iv3<<endl; replace_if(iv.begin(),iv.end(), bind2nd(less<int>(),5), 2); //将所有元素值小于5的改为2 cout<<"replace_if: "<<iv<<endl; replace_copy_if(iv.begin(),iv.end(),iv3.begin(), bind2nd(equal_to<int>(),8), 9); //将所有元素值为8的改为9,结果保存在新容器中 cout<<"replace_copy_if: "<<iv3<<endl; reverse(iv.begin(),iv.end()); cout<<"reverse: "<<iv<<endl; //反转 reverse_copy(iv.begin(),iv.end(),iv3.begin()); cout<<"reverse_copy: "<<iv3<<endl; //反转,结果保存在新容器 rotate(iv.begin(),iv.begin() + 4, iv.end()); cout<<"rotate: "<<iv<<endl; //互换元素 rotate_copy(iv.begin(),iv.begin() + 5,iv.end(),iv3.begin()); cout<<"rotate_copy: "<<iv3<<endl; //互换元素,结果保存在新容器 int ia2[] = {2, 8}; vector<int> iv4(ia2,ia2+2); cout<<"search: "<<*search(iv.begin(),iv.end(),iv4.begin(),iv4.end())<<endl; //查找子序列出现的第一次出现地点 swap_ranges(iv4.begin(),iv4.end(),iv.begin()); //按区域交换 cout<<"swap_ranges: "<<iv<<endl<<iv4<<endl; transform(iv.begin(),iv.end(),iv.begin(),bind2nd(minus<int>(), 2)); //所有元素减2 cout<<"transform: "<<iv<<endl; transform(iv4.begin(),iv4.end(),iv.begin(),iv4.begin(),plus<int>()); //区间对应元素相加 cout<<"transform: "<<iv4<<endl; /************************************************************************/ vector<int> iv5(ia,ia+11); vector<int> iv6(ia+4,ia+8); vector<int> iv7(15); cout<<"max_element: "<<*max_element(iv5.begin(), iv5.end())<<endl; //最大元素游标 cout<<"min_element: "<<*min_element(iv5.begin(), iv5.end())<<endl; cout<<"includes: "<<includes(iv5.begin(),iv5.end(),iv6.begin(),iv6.end())<<endl; //iv6中元素是不是都在iv5中,这两个必须排过序 merge(iv5.begin(),iv5.end(),iv6.begin(),iv6.end(),iv7.begin()); //两个排序号的容器合并 cout<<"merge: "<<iv7<<endl; partition(iv7.begin(),iv7.end(),bind2nd(equal_to<int>(), 5)); //满足条件的放在左边,不满足条件的放在右边 cout<<"partition: "<<iv7<<endl; unique(iv5.begin(),iv5.end()); //去重,重复的元素放在后面 cout<<"unique: "<<iv5<<endl; unique_copy(iv5.begin(),iv5.end(),iv7.begin()); //去重,结果保存在新容器 cout<<"unique_copy: "<<iv7<<endl; }
void RunAdjacentFindCallback() { { // seq AdjacentFindAlgoTest<random_access_iterator_tag> _Alg; _Alg.set_result(adjacent_find(seq, _Alg.begin_in(), _Alg.end_in(), _Alg.callback())); } { //par AdjacentFindAlgoTest<random_access_iterator_tag> _Alg; _Alg.set_result(adjacent_find(par, _Alg.begin_in(), _Alg.end_in(), _Alg.callback())); } { //vec AdjacentFindAlgoTest<random_access_iterator_tag> _Alg; _Alg.set_result(adjacent_find(vec, _Alg.begin_in(), _Alg.end_in(), _Alg.callback())); } }
void RunAdjacentFind() { { // seq AdjacentFindAlgoTest<_IterCat> _Alg; _Alg.set_result(adjacent_find(seq, _Alg.begin_in(), _Alg.end_in())); } { //par AdjacentFindAlgoTest<_IterCat> _Alg; _Alg.set_result(adjacent_find(par, _Alg.begin_in(), _Alg.end_in())); } { //vec AdjacentFindAlgoTest<_IterCat> _Alg; _Alg.set_result(adjacent_find(vec, _Alg.begin_in(), _Alg.end_in())); } }
//if winner, winning_symbol_ set to winner's symbol, else set to default char TicTacToe::findWinner() const { const int NUM_DIAGS = 2; //checks each row for 3-in-a-row winner for (int i = 0; i < game_board_.dimension(); ++i) { std::vector<char> row = game_board_.getRow(i); //checks if all elements the same and not equal to default symbol //adjacent find returns reference to 1st element not equal to front //or row.end() otherwise, all elements same if row.end() is returned if (row.front() != game_board_.getDefaultSymbol() && std::adjacent_find(row.begin(), row.end(), std::not_equal_to<char>()) == row.end()) //row is filled with player symbol, so player symbol is winner return row.front(); } for (int i = 0; i < game_board_.dimension(); ++i) { std::vector<char> col = game_board_.getCol(i); //checks if all elements the same and not equal to default symbol? if (col.front() != game_board_.getDefaultSymbol() && adjacent_find(col.begin(), col.end(), std::not_equal_to<char>()) == col.end()) //col is filled with player symbol, so player symbol is winner return col.front(); } for (int i = 0; i < NUM_DIAGS; ++i) { std::vector<char> diag = game_board_.getDiag(i); //checks if all elements the same and not equal to default symbol? if (diag.front() != game_board_.getDefaultSymbol() && adjacent_find(diag.begin(), diag.end(), std::not_equal_to<char>()) == diag.end()) //col is filled with player symbol, so player symbol is winner return diag.front(); } //return default if no winner return game_board_.getDefaultSymbol(); }
int main() { int ia[] = { 1, 4, 4, 8 }; vector< int, allocator > vec( ia, ia+4 ); int *piter; vector< int, allocator >::iterator iter; // piter points to ia[1] piter = adjacent_find( ia, ia+4 ); assert( *piter = ia[ 1 ] ); // iter points to vec[2] iter = adjacent_find( vec.begin(), vec.end(), TwiceOver() ); assert( *iter = vec[ 2 ] ); // reach here: everything ok cout << "ok: adjacent-find() succeeded!\n"; return 0; }
I operator()(I begin, S end, C pred = C{}, P proj = P{}) const { begin = adjacent_find(std::move(begin), end, std::ref(pred), std::ref(proj)); if(begin != end) { for(I i = next(begin); ++i != end;) if(!invoke(pred, invoke(proj, *begin), invoke(proj, *i))) *++begin = iter_move(i); ++begin; } return begin; }
FwdIt unique(FwdIt first, FwdIt last, IterBinaryPredicate ip) noexcept { first = adjacent_find(first, last, ip); if (first == last) return last; auto dest = first; ++first; while (++first != last) { if (!ip(dest, first)) { *(++dest) = move(*first); } } return ++dest; }
I operator()(I begin, S end, C pred_ = C{}, P proj_ = P{}) const { auto &&pred = invokable(pred_); auto &&proj = invokable(proj_); begin = adjacent_find(std::move(begin), end, std::ref(pred), std::ref(proj)); if(begin != end) { for(I i = next(begin); ++i != end;) if(!pred(proj(*begin), proj(*i))) *++begin = std::move(*i); ++begin; } return begin; }
int main(int argc, const char *argv[]) { // Item 46. Consider function objects instead of functions as algorithm parameters. [ effective stl ] // because we can define function operator as inline function, and the compiler is not optimize for functions even if you // specify it as inline function int a[] = {1, 2, 3, 4}; std::vector<int> ivec(a, a + sizeof(a)/sizeof(int)); std::for_each(ivec.begin(), ivec.end(), Double<int>()); std::for_each(ivec.begin(), ivec.end(), print<int>); std::cout << std::endl; std::for_each(ivec.begin(), ivec.end(), doubleFun<int>); std::for_each(ivec.begin(), ivec.end(), print<int>); std::cout << std::endl; // liner search function, find and find_if // for random iterator, find algorithm use loop expand to optimize typedef std::vector<int>::iterator IVecInterator; IVecInterator iter = find(ivec.begin(), ivec.end(), 5); if (iter == ivec.end()) { std::cout << "could not find 5 in the vector ivec" << std::endl; } // similar with assocative container, they both have count and find member function. there is also count algorithm // count, count_if std::cout << "there is " << std::count(ivec.begin(), ivec.end(), 5) << " in the vector ivec" << std::endl; // search the first same or last same value in the two ranges int b[] = {4, 3, 3, 5, 4}; std::vector<int> ivec2(b, b + sizeof(b)/sizeof(int)); // return the first element in range 2 which occur in the range 1, // in this example, range1 is "4, 8, 12, 16", range 2 is "4, 3, 3, 5, 4" // so return 4 IVecInterator firstIter = find_first_of(ivec.begin(), ivec.end(), ivec2.begin(), ivec2.end()); if (firstIter != ivec.end()) { std::cout << *firstIter << std::endl; } IVecInterator secondIter = find_end(ivec.begin(), ivec.end(), ivec2.begin(), ivec2.end()); if (secondIter != ivec.end()) { std::cout << *secondIter << std::endl; } // find subsequence algorithm // adjacent_find ,return the first duplicated element which are adjacent,otherwise return end IVecInterator adjacent = adjacent_find(ivec2.begin(), ivec2.end()); if (adjacent != ivec2.end()) { std::cout << *adjacent << std::endl; } // search subsequence int c[] = {3, 5, 4}; std::vector<int> ivec3(c, c + sizeof(c)/sizeof(int)); IVecInterator subsequence = search(ivec2.begin(), ivec2.end(), ivec3.begin(), ivec3.end()); if (subsequence != ivec2.end()) { std::cout << *subsequence << std::endl; } // IVecInterator n = search_n(ivec3.begin(), ivec3.end(), // binary search // write only alogrithm // fill_n(dest, cnt, val) // generate_n(dest, cnt, Gen) // copy(beg, end, dest) // transform(beg, end, dest, unaryOp) // transform(beg, end, beg2, dest, binaryOp) // merge(beg1, end1, beg2, end2, dest) // merge(beg1, end1, beg2, end2, dest, comp) // sort and partition algorithm // partition, stable_partition // stable_partition(beg, end, unaryPred) // partition(beg, end, unaryPred) // sort, stable_sort, partitial_sort // nth_element // general reorder algorithm // unique, reverse, rotate, remove, remove_if // remove_copy, unique_copy, rotate_copy, random_shuffle // permutation alogrithm // prev_permutation(beg, end), next_permutation(beg, end) int a5[] = {1, 2, 3, 4}; std::vector<int> ivec5(a5, a5 + 4); // alogrithm for next_permutation : std::next_permutation(ivec5.begin(), ivec5.end()); std::for_each(ivec5.begin(), ivec5.end(), print<int>); std::cout << std::endl; std::next_permutation(ivec5.begin(), ivec5.end()); std::for_each(ivec5.begin(), ivec5.end(), print<int>); std::cout << std::endl; // ordered set algorithm : set_union, set_intersection, set_difference, set_symmetric_difference // compare algorithm // min(val1, val2), max(val1, val2), min_element, max_element(beg, end) // math algorithm return 0; }
int main(int argc, char *argv[]) { /* * Initialize IPRT and convert argv to UTF-8. */ int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Parse arguments and read input files. */ if (argc < 4) { usage(stderr, argv[0]); return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Insufficient arguments."); } g_products.reserve(20000); g_vendors.reserve(3500); const char *pszOutFile = NULL; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-o") == 0) { pszOutFile = argv[++i]; continue; } if ( strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0 || strcmp(argv[i], "--help") == 0) { usage(stdout, argv[0]); return RTEXITCODE_SUCCESS; } PRTSTREAM pInStrm; rc = RTStrmOpen(argv[i], "r", &pInStrm); if (RT_FAILURE(rc)) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Failed to open file '%s' for reading: %Rrc", argv[i], rc); rc = ParseUsbIds(pInStrm, argv[i]); RTStrmClose(pInStrm); if (rc != 0) { RTMsgError("Failed parsing USB devices file '%s'", argv[i]); return rc; } } /* * Due to USBIDDBVENDOR::iProduct, there is currently a max of 64KB products. * (Not a problem as we've only have less that 54K products currently.) */ if (g_products.size() > _64K) return RTMsgErrorExit((RTEXITCODE)ERROR_TOO_MANY_PRODUCTS, "More than 64K products is not supported: %u products", g_products.size()); /* * Sort the IDs and fill in the iProduct and cProduct members. */ sort(g_products.begin(), g_products.end()); sort(g_vendors.begin(), g_vendors.end()); size_t iProduct = 0; for (size_t iVendor = 0; iVendor < g_vendors.size(); iVendor++) { size_t const idVendor = g_vendors[iVendor].vendorID; g_vendors[iVendor].iProduct = iProduct; if ( iProduct < g_products.size() && g_products[iProduct].vendorID <= idVendor) { if (g_products[iProduct].vendorID == idVendor) do iProduct++; while ( iProduct < g_products.size() && g_products[iProduct].vendorID == idVendor); else return RTMsgErrorExit((RTEXITCODE)ERROR_IN_PARSE_LINE, "product without vendor after sorting. impossible!"); } g_vendors[iVendor].cProducts = iProduct - g_vendors[iVendor].iProduct; } /* * Verify that all IDs are unique. */ ProductsSet::iterator ita = adjacent_find(g_products.begin(), g_products.end()); if (ita != g_products.end()) return RTMsgErrorExit((RTEXITCODE)ERROR_DUPLICATE_ENTRY, "Duplicate alias detected: idProduct=%#06x", ita->productID); /* * Build the string table. * Do string compression and create the string table. */ BLDPROGSTRTAB StrTab; if (!BldProgStrTab_Init(&StrTab, g_products.size() + g_vendors.size())) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Out of memory!"); for (ProductsSet::iterator it = g_products.begin(); it != g_products.end(); ++it) { it->StrRef.pszString = (char *)it->str.c_str(); BldProgStrTab_AddString(&StrTab, &it->StrRef); } for (VendorsSet::iterator it = g_vendors.begin(); it != g_vendors.end(); ++it) { it->StrRef.pszString = (char *)it->str.c_str(); BldProgStrTab_AddString(&StrTab, &it->StrRef); } if (!BldProgStrTab_CompileIt(&StrTab, g_fVerbose)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "BldProgStrTab_CompileIt failed!\n"); /* * Print stats. Making a little extra effort to get it all on one line. */ size_t const cbVendorEntry = sizeof(USBIdDatabase::s_aVendors[0]) + sizeof(USBIdDatabase::s_aVendorNames[0]); size_t const cbProductEntry = sizeof(USBIdDatabase::s_aProducts[0]) + sizeof(USBIdDatabase::s_aProductNames[0]); size_t cbOldRaw = (g_products.size() + g_vendors.size()) * sizeof(const char *) * 2 + g_cbRawStrings; size_t cbRaw = g_vendors.size() * cbVendorEntry + g_products.size() * cbProductEntry + g_cbRawStrings; size_t cbActual = g_vendors.size() * cbVendorEntry + g_products.size() * cbProductEntry + StrTab.cchStrTab; #ifdef USB_ID_DATABASE_WITH_COMPRESSION cbActual += sizeof(StrTab.aCompDict); #endif char szMsg1[32]; RTStrPrintf(szMsg1, sizeof(szMsg1),"Total %zu bytes", cbActual); char szMsg2[64]; RTStrPrintf(szMsg2, sizeof(szMsg2)," old version %zu bytes + relocs (%zu%% save)", cbOldRaw, (cbOldRaw - cbActual) * 100 / cbOldRaw); if (cbActual < cbRaw) RTMsgInfo("%s - saving %zu%% (%zu bytes);%s", szMsg1, (cbRaw - cbActual) * 100 / cbRaw, cbRaw - cbActual, szMsg2); else RTMsgInfo("%s - wasting %zu bytes;%s", szMsg1, cbActual - cbRaw, szMsg2); /* * Produce the source file. */ if (!pszOutFile) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Output file is not specified."); FILE *pOut = fopen(pszOutFile, "w"); if (!pOut) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Error opening '%s' for writing", pszOutFile); WriteSourceFile(pOut, argv[0], &StrTab); if (ferror(pOut)) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Error writing '%s'!", pszOutFile); if (fclose(pOut) != 0) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Error closing '%s'!", pszOutFile); return RTEXITCODE_SUCCESS; }
int findDuplicate(vector<int>& nums) { sort(nums.begin(), nums.end()); vector<int>::iterator it = adjacent_find(nums.begin(), nums.end()); return *it; }