C++ Primer: Chapter 11 Associative-container

Code

11.3.6 单词转换程序

map<string, string> buildMap(ifstream& map_file)
{
	map<string, string> trans_map;
	string key;
	string value;

	while (map_file >> key && getline(map_file, value))
		if (value.size() > 1)
			trans_map[key] = value.substr(1);
		else
			throw runtime_error("no rule for " + key);

	return trans_map;
}

const string& transform(const string& s, const map<string, string>& m)
{
	auto map_it = m.find(s);
	if (map_it != m.cend())
		return map_it->second;
	else
		return s;
}

void word_transform(ifstream& map_file, ifstream& input)
{
	auto trans_map = buildMap(map_file);
	string text;
	while (getline(input, text))
	{
		istringstream strin(text);
		string word;
		bool firstword = true;
		while (strin >> word)
		{
			if (firstword)
				firstword = false;
			else
				cout << " ";
			cout << transform(word, trans_map);
		}
		cout << endl;
	}

}

int main()
{
	ifstream frule("rule.txt");
	ifstream fin("infile.txt");
	word_transform(frule, fin);

	return 0;
}

11.4 无序容器的哈希函数

在C++中,无序容器(如std::unordered_mapstd::unordered_set等)使用哈希函数来将键(key)映射到容器中的位置。C++标准库提供了默认的哈希函数,但也允许用户自定义哈希函数。

默认情况下,C++标准库提供了一系列用于内置类型(如intdoublestd::string等)的哈希函数。对于自定义类型,用户可以提供自己的哈希函数。

以下是一个使用自定义哈希函数的示例:

// 自定义哈希函数
struct MyHash {
    std::size_t operator()(const std::string& str) const {
        std::size_t hash = 0;
        for (char ch : str) {
            hash = hash * 31 + ch; // 使用31作为乘子,这是一种常用的哈希算法
        }
        return hash;
    }
};

int main() {
    // 使用自定义哈希函数创建unordered_map
    std::unordered_map<std::string, int, MyHash> myMap;

    // 插入键值对
    myMap["apple"] = 5;
    myMap["banana"] = 3;
    myMap["orange"] = 7;

    // 访问值
    std::cout << "Number of apples: " << myMap["apple"] << std::endl;

    return 0;
}

在这个例子中,MyHash是一个自定义的哈希函数对象,它重载了函数调用运算符operator()来计算字符串的哈希值。然后,我们使用这个自定义的哈希函数类作为std::unordered_map的第三个模板参数,以指定键类型为std::string时要使用的哈希函数。

自定义哈希函数时,要确保哈希函数能够均匀地将不同的键映射到不同的位置,以提高无序容器的性能。

Homework

Test 11.3

int main()
{
	map<string, size_t> word_count;
	set<string> exclude = { "The", "But", "And", "Or", "An", "A", "the", "but", "and", "or", "an", "a" };

	string word;
	ifstream fin("infile.txt");
	while (fin >> word)
	{
		if (exclude.find(word) == exclude.end())
			++word_count[word];
	}

	//cout map contents
	for (auto& w : word_count)
		cout << w.first << " occurs " << w.second << (w.second > 1 ? " times" : " time") << endl;


	return 0;
}

Test 11.4

int main()
{
	map<string, size_t> word_count;
	set<string> exclude = { "The", "But", "And", "Or", "An", "A", "the", "but", "and", "or", "an", "a" };

	string word;
	ifstream fin("infile.txt");
	while (fin >> word)
	{
		//handle upper and punctuation
		for (string::iterator beg = word.begin(); beg != word.end(); )
		{
			if (isupper(*beg))
			{
				*beg = tolower(*beg);
				++beg;
			}
			else if (ispunct(*beg))
				beg = word.erase(beg);
			else
				++beg;
		}

		if (exclude.find(word) == exclude.end())
			++word_count[word];
	}

	//cout map contents
	for (auto& w : word_count)
		cout << w.first << " occurs " << w.second << (w.second > 1 ? " times" : " time") << endl;


	return 0;
}

Test 11.7

void add_family(map<string, vector<string>>& fc, const string& family, const vector<string>& childs)
{
	auto it = fc.find(family);
	
	if (it == fc.end())
		fc[family] = childs; //如果不在,创建family键
	else 
		copy(childs.begin(), childs.end(), back_inserter(fc[family])); //如果在,追加新Childs
		
}
int main()
{
	map<string, vector<string>> family_child;

	add_family(family_child, "He", { "jian", "gan" });
	add_family(family_child, "Mu", { "ou", "hua" });
	add_family(family_child, "He", { "wen" });

	for (auto& f : family_child)
		cout << f.first << " ";
	for (auto& s : family_child["He"])
		cout << s << " ";

	return 0;
}

Test 11.9

map<string, list<int>> word_row;

Test 11.11

bool compareIsbn(const my_sales_data& lhs, const my_sales_data& rhs)
{
	return lhs.isbn() < rhs.isbn();
}
int main()
{
	typedef bool (*pf)(const my_sales_data& lhs, const my_sales_data& rhs); //pf是指向bool (const my_sales_data& lhs, const my_sales_data& rhs)函数类型的指针
	multiset<my_sales_data, pf> bookstore(compareIsbn);

	return 0;
}

Test 11.12

int main()
{
	vector<pair<string, int>> pvec;

	ifstream fin("infile.txt");
	string str;
	int i;
	while (fin >> str && fin >> i)
		pvec.push_back(make_pair(str, i));

	for (auto& p : pvec)
		cout << p.first << " " << p.second << endl;


	return 0;
}

Test 11.14

void add_family(map<string, vector<string>>& fc, const string& family, const vector<string>& childs)
{
	auto it = fc.find(family);

	if (it == fc.end())
		fc[family] = childs; //如果不在,创建family键
	else
		copy(childs.begin(), childs.end(), back_inserter(fc[family])); //如果在,追加新Childs

}
int main()
{
	map<string, vector<string>> family_child;

	pair<string, string> cild_date;
	add_family(family_child, "He", { "jian", "gan" });
	add_family(family_child, "Mu", { "ou", "hua" });
	add_family(family_child, "He", { "wen" });

	vector<pair<string, string>> cdvec;

	for (auto& f : family_child)
		for (auto beg = f.second.begin(); beg != f.second.end(); ++beg)
			cdvec.push_back(make_pair(*beg, *beg + "'s birthday"));
	for (auto& cd : cdvec)
		cout << cd.second << " ";

	return 0;
}

Test 11.16

map<string, int> dict{ {"hello", 5}, {"world", 4} };
auto it = dict.begin();
it->second = 2;

cout << it->second << endl;

Test 11.19

typedef bool (*pf)(const my_sales_data& lhs, const my_sales_data& rhs); //pf是指向bool (const my_sales_data& lhs, const my_sales_data& rhs)函数类型的指针
multiset<my_sales_data, pf> bookstore(compareIsbn);

multiset<my_sales_data, pf>::iterator var = bookstore.begin();

Test 11.22

map<string, vector<int>> m;
pair<map<string, vector<int>>::iterator, bool> var = m.insert(make_pair("瓶子君", vector<int>{1, 5, 2}));

Test 11.23

multimap<string, string> family_childs;
family_childs.insert(make_pair("He", "jian"));
family_childs.insert(make_pair("He", "gan"));
family_childs.insert(make_pair("Mu", "ou"));
family_childs.insert(make_pair("Mu", "hua"));

for (auto& f : family_childs)
	cout << f.first << " " << f.second << endl;

Test 11.31

void findele(multimap<string, string> &mm, const string &name)
{
	auto it = mm.find(name);
	if (it != mm.end())
	{
		it = mm.erase(it);
		if (it->first == name)
			it = mm.erase(it);
	}
	else
		cout << "no element" << endl;

}
int main()
{
		
	multimap<string, string> mm{
		make_pair("Hou", "<stl源码剖析>"), make_pair("Hou", "<泛型思维>"), make_pair("Li", "<C++>"),
		make_pair("Li", "<lulu>"), make_pair("Ji", "<引擎开发>")
	};

	findele(mm, "Li");

	for (auto s : mm)
		cout << s.first << " " << s.second << " ";

	return 0;
}

Test 11.33

map<string, string> buildMap(ifstream& map_file)
{
	map<string, string> trans_map;
	string key;
	string value;

	while (map_file >> key && getline(map_file, value))
		if (value.size() > 1)
			trans_map[key] = value.substr(1);
		else
			throw runtime_error("no rule for " + key);

	return trans_map;
}

const string& transform(const string& s, const map<string, string>& m)
{
	auto map_it = m.find(s);
	if (map_it != m.cend())
		return map_it->second;
	else
		return s;
}

void word_transform(ifstream& map_file, ifstream& input)
{
	auto trans_map = buildMap(map_file);
	string text;
	while (getline(input, text))
	{
		istringstream strin(text);
		string word;
		bool firstword = true;
		while (strin >> word)
		{
			if (firstword)
				firstword = false;
			else
				cout << " ";
			cout << transform(word, trans_map);
		}
		cout << endl;
	}

}

int main()
{
	ifstream frule("rule.txt");
	ifstream fin("infile.txt");
	word_transform(frule, fin);

	return 0;
}

Test 11.38

int main()
{
	unordered_map<string, size_t> word_count;
	set<string> exclude = { "The", "But", "And", "Or", "An", "A", "the", "but", "and", "or", "an", "a" };

	string word;
	ifstream fin("infile.txt");
	while (fin >> word)
	{
		if (exclude.find(word) == exclude.end())
			++word_count[word];
	}

	//cout map contents
	for (const auto& w : word_count)
		cout << w.first << " occurs " << w.second << (w.second > 1 ? " times" : " time") << endl;


	return 0;
}
unordered_map<string, string> buildMap(ifstream& map_file)
{
	unordered_map<string, string> trans_map;
	string key;
	string value;

	while (map_file >> key && getline(map_file, value))
		if (value.size() > 1)
			trans_map[key] = value.substr(1);
		else
			throw runtime_error("no rule for " + key);

	return trans_map;
}

const string& transform(const string& s, const unordered_map<string, string>& m)
{
	auto map_it = m.find(s);
	if (map_it != m.cend())
		return map_it->second;
	else
		return s;
}

void word_transform(ifstream& map_file, ifstream& input)
{
	auto trans_map = buildMap(map_file);
	string text;
	while (getline(input, text))
	{
		istringstream strin(text);
		string word;
		bool firstword = true;
		while (strin >> word)
		{
			if (firstword)
				firstword = false;
			else
				cout << " ";
			cout << transform(word, trans_map);
		}
		cout << endl;
	}

}

int main()
{
	ifstream frule("rule.txt");
	ifstream fin("infile.txt");
	word_transform(frule, fin);

	return 0;
}
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值