天天看點

讀書筆記:C++ primer 5th edition--chapter17.标準庫特殊設施

part1.tuple類型 1.一個tuple可以有任意數量的成員。每個确定tuple類型的成員數目是固定的。是一個快速而随意的資料結構。 2.構造函數是explicit,必須使用直接初始化: tuple< size_t, size_t, size_t > threeD{1, 2, 3}; 3.make tuple使用初始值的類型來推斷tuple類型。 auto item = make_tuple( “0-999-xxx”,3, 20.00); 4.使用get通路成員 auto book = get<0>(item);//第一個元素 5.tuple的類型資訊 typedef decltype(item) trans; size_t sz = tuple_size<trans>:: value;//元素數量 tuple_element<1, trans >::type cnt = get<1>(item);//cnt表示得到的類型 6.常見用途是從一個函數傳回多個值 vector<matches> ret; ret.push_back(make_tuple(xxx,xxx,xxx) ); return ret;

part2.bitset類型 1.初始化 bitset<32> bitvec(1U);//32位,低位為1 2.用unsigned 值初始化bitset,如果bitset大小大于一個unsigned long long 中的二進制位數,則剩餘高位被置零。 否則,隻使用給定值的低位,超出bitset部分被丢棄。 3.也可以從string初始化bitset。此時字元串中最小的字元對應高位。 4.常用函數 any(),all(),none(),count().都是針對是否有1而言的。不接受參數,對整個集合執行給定操作。 set(pos,v),reset(pos),flip(pos).接受一個位置參數的版本則對指定位執行操作。 to_string(zero, one); 5.如果bitset中的值不能放入給定類型中(bitset太小了),會有異常。 to_ulong() to_ullong()

part3.正規表達式 1.regex類表示一個正規表達式。 2.regex_match,regex_search确定一個給定字元序列與一個給定regex是否比對。 如果整個輸入序列與表達式比對,則regex_match函數傳回true。 如果輸入序列中的一個子串與表達式比對,則regex_search函數傳回true。 3.用法: string pattern(“ [^c]ei ”); pattern = “[ [ :alpha: ] ]* ” + pattern + “[ [ :alpha: ] ]*”;     //“[ [ :alpha: ] ]*”;表示零個或多個字母。 regex r(pattern, regex::icase);//忽略大小寫 smatch results; string test_str = “xxx xxx xxx”; for(sregex_iterator it(test_str.begin(), test_str.end(), r ), end_it;           it != end_it; ++it )  {   // end_it是一個空sregex_iterator,起到尾後疊代器的作用           cout << it->str() << endl;//輸出所有比對,而非隻是第一個           //還可以輸出比對位置的上下文:字首以及字尾           auto pos = it->prefix().length();     //suffix是字尾           pos = pos > 40 ? pos - 40 : 0;           cout << it->prefix().str().substr(pos ); } 4.預設使用ECMAScript規範。還有其他的比如awk, grep等 5.正規表達式的文法是在運作時解析的。編譯過程很慢,是以不建議放入循環中多次建立。 6.正規表達式庫類 string               regex,smatch,sregex_iterator const char*     regex, cmatch, cregex_iterator 7.使用子表達式 1)正規表達式語言特性 \{d}{3}比對三個數字的序列 [-.]方括号表示比對這些字元中的任意一個。點在括号裡沒有特殊含義 ?表示元件是可選的。 \是特殊字元,括号( 也是特殊字元。是以用\(表示括号使我們模式的一部分而不是特殊字元。用\\表示需要的是反斜線而不是特殊符号。 2)多個表達式:比對電話号碼 908.555.1800 (\\()? 表示區号部分 可選的左括号 (\\d{3})表示區号 (\\))?可選的右括号 ([-. ])?可選的分隔符 對于七個字表達式的pattern,每個smatch對象會包含八個ssub_match,[0]表示整個比對。[1]…[7]表示對應的表達式。 即使有一個完整的比對了,我們還是不知道每個可選的子表達式是否是比對的一部分。如果是的話,則其對應的ssub_match對象的matched成員為true。 判斷括号比對可以用: bool valid(const smatch& m) {      if(m[1].matched) &&m[3].matched           //then } 調用時: for(sregex_iterator it(test_str.begin(), test_str.end(), r ), end_it;           it != end_it; ++it )      if(valid (*it) ){ ….}     //*it 就是smatch類型 8.使用regex_replace //在替換的字元串中使用第二個,第五個和第七個子表達式,其餘的忽略。 string fmt = “$2.$5.$7”; regex r(phone); string number = “(908) 555-1800”; cout << regex_replace(number, r, fmt ) << endl; //output: 908.555.1800,被格式化 cout << regex_replace(number, r, fmt, format_no_copy ) << endl; //隻拷貝它替換的文本,不輸出未比對的部分

part4.随機數 1.随機數庫組成:  引擎,生成随機的unsigned整數序列                               分布,使用引擎 傳回服從特定機率分布的随機數 2.用法: default_random_engine e; while(1)      cout<< e() << endl;     //随機數引擎的輸出不能直接用,因為值的範圍與我們要求的不符,需要正确轉換範圍 3.是以應該是: uniform_int_distribution< unsigned> u(0, 9);//生成0到9之間的均勻分布随機數 default_random_engine e; while(1)      cout<< u(e) << endl;//不是u(e() ),我們傳遞的是引擎本身,而不是它的下一個值。 4.是以,随機數發生器是指分布對象和引擎對象的組合。 5.編寫生成的函數應該這樣: vector<unsigned> goog_randVec(){       static default_random_engine e;     //不加static,則每次生成的100個随機數都是一樣的。       staic uniform_int_distribution<unsigned> u(0, 9);     //是以序列一樣有利于調試,但一旦正式使用,需要不一樣      vector<unsigned> ret;      for(;i<100;)           ret.push_back( u(e) );      return ret; } 6.可以使用時間種子  default_random_engine e1(time(0));//适用于生成種子的間隔為秒級或更長的應用。 7.生成随機浮點數  default_random_engine e; uniform_real_distribution<double> u(0, 1); //或使用分布模闆的預設結果類型,為double uniform_real_distribution<> u(0, 1); 8.其他分布 normal_distribution <> n(4, 1.5);//mean = 4, var = 1.5 bernoulli_distribution b;//預設是50/50 bernoulli_distribution b(0.55);//55/45

part5.IO庫再探 1.當操縱符改變流的狀态時,通常改變後的狀态對後續都生效,是以不用的時候需要恢複為預設。 2.作用: 1)可以按進制列印,加上進制資訊:0x 2)指定列印精度 cout.setprecision(12); 3)列印小數點 cout << showpoint << 10.0 << noshowpoint << endl; 4)輸出補白: setfill() left,right, setw cout << setfill(‘#’)            <<“i = “ << setw(12) << i << ‘\n’ ;//以’\n’為機關進行左右對齊,以及字元站位,填充。           <<setfill(‘ ‘ );//恢複到正常補白字元 3.未格式化的輸入輸出 char ch; while (cin.get(ch))      cout.put(ch); 使用peek,unget,putback,可以退回最多一個值。傳回類型是int,而非char,為了存儲更多資訊,可以傳回檔案尾标記。 4.流随機通路 iostream 不支援。隻适用于fstream和sstream seek,tell。 fstream inOut(“”,fsteram::ate); auto end_mark = inOut.tellg(); inOut.seekg(0, fstream::beg); 

繼續閱讀