千慮一得齋OnLine_觀死書齋-Yahoo/Hexun/Blogger/sina/Xuite

觀死書齋暨Spread、和訊博客全文檢索

2019年11月2日 星期六

C++自修入門實境秀、C++ Primer 5版研讀秀 74/ ~ v11關聯式容器~11.3.5. Accessing Elements-2...



11.3.4. Subscripting a map

11.3.4為一個map添標

中文版前均翻成「下標(subscript)」

→對map容器下標(subscript)

set容器因為沒有對應於鍵值的值,所以就不具下標(subscript)運算

map與unordered_map都提供了下標運算子還有對應的at成員函式。(Subscripting and Safe Random Access,頁348)

map的下標運算是由鍵值作為索引值來提取對應的值,然而map的下標運算卻會在找不到符合的鍵值時,插入一個新的元素。參見表11.6



頁436

Table 11.6. Subscript Operation for map and unordered_map

表11.6 : map與unordered_map的下標運算

c[k] 回傳帶有鍵值k的元素;如果c中沒有k,就新增具有鍵值k的一個 新的、值初始化的元素。



c.at(k) 檢查對具有鍵值k的元素之存取權;如果k不在c中,就擲出一個 out of range 例外(§ 5.6 ) °

41:13

Using the Value Returned from a Subscript Operation

使用下標運算回傳的值

當對map做下標時,回傳的會是mapped_type(即及「值」的型別),而對map的迭代器作解參考(dereference)則會得到pair的型別(value_type)

⑧找對主詞

一個是元素值(迭代器所指)一個是元素下面的「值」(即mapped_type),下標針對的是這個「值」,不是元素值。

map下標回傳的值是左值(lvalue),因為是左值,所以我們可以藉由此左值(傳址(pass by reference))來改動其所指的元素下面的「值」(mapped_type型別的物件)。

鍵值(key_type)是不能動的const,而值(mapped_type)是可以動的。

52:50

11.3.5. Accessing Elements

存取關聯式容器(associative container)中的元素

58:07

find()

只要找到元素,不管它有幾個,就用find

count()

要計數(符合條件的元素有幾個)才用count



頁437



1:1:40 1:4:22

頁437

習題章節11.3.4

練習11.24

1:4:50

#include<iostream>

#include<map>

using namespace std;

int main() {

map<int,int> m;

cout << m.size() << endl;//=0

m[0] = 1;

cout << m.size() << endl;//=1

cout << m.begin()->first << ":" << m.begin()->second << endl;//=「0:1」

}

1:10:40

練習11.25

#include<iostream>

#include<vector>

using namespace std;

int main() {

vector<int> v;

cout << v.size() << endl;//=0

//v[0] = 1;//error :vector subscript out of range

try

{

v.at(0) = 1;

}

catch (const std::exception& ex)

{

cout << v.size() << endl;//=0

cerr << ex.what() << endl;

}

}

1:16:59 1:20:30

練習11.26

map下標(subscript)針對的是mapped_type(元素下面的那個「值」),回傳的是mapped_type

是藉由key_type來找到mapped_type,所以只要是與key_type相容的型別均可用來下標

#include<iostream>

#include<map>

using namespace std;

int main() {

map<int, string>m;//下標(subscript)要用角括弧中逗號前的相容型別,下標回傳的型別則為逗號後的型別

cout << m.size() << endl;//=0

m[1.1] = "i";

cout << m.size() << endl;//=1

cout << m.begin()->first << ":" << m.begin()->second << endl;//=1:i

/*Warning C4244 'argument': conversion from 'double' to 'int', possible loss of data*/

string s = m[1.3];

auto as = m[1.3];//type of as is string

cout << m.size() << endl;//=1

cout << m.begin()->first << ":" << m.begin()->second << endl;//=1:i

}





1:57:30

Using find Instead of Subscript for maps

這一段,了無新意,前面內容都已提過了。

Finding Elements in a multimap or multiset

頁438

Table 11.7. Operations to Find Elements in an Associative Container

表11.7 :在一個關聯式容器中尋找元素的運算

lower_bound與upper_bound對無序容器來說無效。

下標和at運算只能用於不是const的map與unordered_map。

c.find(k) 回傳一個迭代器指向(第一個)具有鍵值k的元素,或在k不存於容 器中時,回傳off_the_end迭代器。

c.count(k) 回傳具有鍵值k的元素之數目。對於具有唯一鍵值的容器,結果永遠會是零或一。

c.lower_bound(k) 回傳一個迭代器指向具有的鍵值不小於k的第一個元素。

c.upper_bound(k) 回傳一個迭代器指向具有的鍵值大於k的第一個元素。

c.equal_range(k)

回傳一對迭代器代表具有鍵值k的那些元素。如果k沒出現,那兩個成員都會是c.end()。

Returns a pair of iterators denoting the elements with key k. If k is

not present, both members are c.end().

這裡「一對」原文是特殊字體(應是Courier New) 則指的是「pair」型別,不該翻成中文

兩個成員原文是both members,即專指pair型別中的二個成員



2:4:10 2:11:30

string search_item("Alain de Botton"); // author we'll look for

auto entries = authors.count(search_item); // number of elements

auto iter = authors.find(search_item); // first entry for this author

// loop through the number of entries there are for this author

while (entries)

{

cout << iter->second << endl; // print each title

++iter; // advance to the next title

--entries; // keep track of how many we've printed

}

The number of iterations of the forloop depends on the number returned from count .

明明例子是用「while」,英文版誤矣!

2:18:00

中文版翻譯有誤:

We are guaranteed that iterating across a multimap or multiset returns all the elements with a given key in sequence.

我們可以保證,迭代過一個multimap或multiset會回傳一個序列中具有給定鍵值的所有元素

我們有把握

are guaranteed that是被動式

會按順序地回傳所有符合指定鍵值的元素出來

A Different, Iterator-Oriented Solution

Iterator-Oriented可譯為「迭代器模式」(行為模式的模式)左包含區間 迭代器範圍(iterator range)

lower_bound()

upper_bound()



2:25:40

即兩個夾起來的邊界範圍Iterator Ranges

如果在一個multimap中找不到指定的鍵值,那麼:lower_bound()==upper_bound()

這兩個成員函式傳回的迭代器會指向可以插入該鍵值元素的適當位置:

both will refer to the point at which the key can be inserted without disrupting the order.

頁439

這整頁幾乎都了無新意,重複前述,只是換句話說而已

3:4:05

The equal_range Function

equal_range()

此一成員函式也不過就是把lower_bound與upper_bound合併嘛

equal ⑦先抓動詞 ⑧找對主詞 與誰equal?與鍵值equal

頁440

3:15:50

練習11.27

會用count()成員函式去解決怎樣的問題?

需要計數時才用上。只要知道某鍵值的元素存不存在關聯式容器中就不必了,用find()即可

練習11.28

3:18:44

#include<iostream>

#include<map>

#include<vector>

using namespace std;

int main() {

vector<int>v{1,2};

map<string, vector<int>>m;//{ "營利事業所得稅",v },

m["孫守真"] = v;

string s("守真");

map<string, vector<int>>::iterator it = m.find(s);

}

3:27:55

練習11.29

#include<iostream>

#include<iterator>

#include<map>

#include<vector>

using namespace std;

int main() {

vector<int>v{ 1,2 };

map<string, vector<int>>m;

m["孫守真"] = v;

istream_iterator<string>in(cin), end;

while (in != end)

m.insert(make_pair(*in++, v));

string s("守真");

map<string, vector<int>>::iterator it = m.find(s);

map<string, vector<int>>::iterator itL = m.lower_bound(s);

map<string, vector<int>>::iterator itU = m.upper_bound(s);

pair<map<string, vector<int>>::iterator, map<string, vector<int>>::iterator>

itE = m.equal_range(s);

if (itL == itE.first)

cout << "lower=first" << endl;

if (itU == itE.second)

cout << "upper=second" << endl;

if (itL == itU)

cout << "not found" << endl;

if (itE.first == itE.second)

{

cout << "not found" << endl;

cout << (itE.first)->first << endl;//可見可插入位置也如前循序容器的insert都是在前位插入要插入的元素

m.insert(itE.first, make_pair(s, v));

}

decltype(m.cbegin()) itM = m.cbegin();

while (itM != m.cend())

{

cout << itM++->first << endl;

}

}

3:55:44

練習11.30

因為equal_range()成員函式傳的是pair<map::iterator, map::iterator >,所以pos.first就是逗點前一個iterator,將此迭代器解參考後即是map的元素,而存取map元素的鍵值與值的對組(pair)中的第2個資料成員(data member)pos.first->second,在這裡就是作者的作品。

練習11.31

4:0:44

Write a program that defines a multimap of authors and their works. Use find to find an element in the multimap and erase that element. Be sure your program works correctly if the element you look for is not in the map.

此map,應當作普通字體,表示multimap。

中文版也未訂正。

6:26:20 6:33:00

#include<iostream>

#include<iterator>

#include<map>

using namespace std;

int main() {

multimap<string, string>m;

istream_iterator<string>in(cin), end;

string a;

while (in != end)

{

a = *in;

m.insert(make_pair(a, *++in)); ++in;

}

string s("孫守真");

multimap<string, string>::iterator it = m.find(s);//此下三式用map也行,不必用multimap

multimap<string, string>::iterator itL = m.lower_bound(s);

multimap<string, string>::iterator itU = m.upper_bound(s);

pair<multimap<string, string>::iterator, multimap<string, string>::iterator>itE = m.equal_range(s);

if (itL == itE.first)

cout << "lower=first" << endl;

if (itU == itE.second)

cout << "upper=second" << endl;

if (itL == itU)

cout << "not found" << endl;

if (itE.first == itE.second)

{

cout << "not found" << endl;

cout << (itE.first)->first << endl;//可見可插入位置也如前循序容器的insert都是在前位插入要插入的元素

}

if (itL != itU&&it!=m.end()&& itE.first!=itE.second)

m.erase(s);

decltype(m.cbegin()) itM = m.cbegin();

while (itM != m.cend())

{

cout << itM++->first<<":"<< itM->second << endl;

}

}

6:59:08

練習11.32

已詳見前一題。

Word VBA插入214部首常用字

4:8:00 完成 https://snipsave.com/oscarsun72/#/snippet/xi3BP0p77YFJyKjCfY

Word VBA插入部件構字及諧聲構字(聲符構字)

5:1:49

5:59:00 部件構字列出,測試成功 https://snipsave.com/oscarsun72/#/snippet/67DOd8bFEuJtt386uZ

5:59:40 聲符構字列出,測試成功 6:26:00 https://snipsave.com/oscarsun72/#/snippet/3g20TSMclAyO5ExDyk



4:19:10

VB 如何關閉指定的表單 https://ithelp.ithome.com.tw/questions/10195912?sc=nl.daily

4:56:17 OK



11.3.6. A Word Transformation Map

11.3.6 一個字詞變換映射

沒有留言:

張貼留言