栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

map,unordered

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

map,unordered

文章目录
    • c++里面的typedef和using
    • 统计字符串中字符出现的次数
    • map的find函数
    • set有一定的查重功能,但是不能知道重复数据的个数
    • lambda表达式的引入
    • lambda表达式语法
    • 捕获列表说明

map底层的实现是一个红黑二叉树

c++里面的typedef和using
typedef pair value_type;
using value_type=pair;
二者等价
typedef int* PINT;
using PINT=int *;
统计字符串中字符出现的次数

在map中[]运算符的重载的工能是访问或插入指定的元素”

emplate
class map
{
	typedef pair<_Key, _Val> value_type;
};
//T树
//哈希表
//map

int main()
{//统计字符串中字符出现的次数
	string stra[] = { "map","duque","queue","vector","list","map","vector","map" };
	std::mapsimap;
	//        key-->value
	for (auto& x : stra)
	{
		simap[x] += 1;
	}
	std::map::iterator it = simap.begin();//双向迭代器
	for (; it != simap.end(); ++it)
	{
		cout << it->first << "==>" << it->second << endl;
	}
	return 0;
}

#include//哈希表
template
class map
{
	typedef pair<_Key, _Val> value_type;
};
//T树
//哈希表
//map

int main()
{//统计字符串中字符出现的次数
	string stra[] = { "map","duque","queue","vector","list","map","vector","map" };
	std::mapsimap;//底层是红黑树,通过string的字符顺序比较排序
	//        key-->value
	std::unordered_mapunmap;//无序map 底层的实现是哈希表
	for (auto& x : stra)
	{
		simap[x] += 1;
		unmap[x] += 1;
	}
	std::map::iterator it = simap.begin();
	for (; it != simap.end(); ++it)
	{
		cout << it->first << "==>" << it->second << endl;
	}
	std::unordered_map::iterator uit=unmap.begin();
	for (;uit!=unmap.end();++uit)
	{
		cout << uit->first << " " << uit->second << endl;
	}
	return 0;
}

#include
int main()
{
	std::mapage_namemap;
	int age;
	string name;
	while (cin >> age >> name, age >= 16 && name != "end")
	{
	//以下三种都可以
		age_namemap[age] = name;
		age_namemap.insert(std::map::value_type(age, name));
		age_namemap.insert(pair(age, name));
	}
	for (auto& x : age_namemap)
	{
		cout << x.first << "--> " << x.second << endl;
	}
}

#include
int main()
{
	std::multimapanmap;//允许关键码重复
	std::mapnamap;//不允许关键码重复
	namap[23] = "yhping";
	namap[16] = "gg";
	namap[23] = "hello";
	for (auto& x : namap)
	{
		cout << x.first << " " << x.second << endl;
	}
	return 0;

}

int main()
{
	std::multimapanmap;//底层是红黑树,允许关键码重复,不支持[]运算符
	std::mapnamap;//不允许关键码重复
	//namap[23] = "yhping";
	//namap[16] = "gg";
	//namap[23] = "hello";
	anmap.insert(map::value_type(23, "yhping"));
	anmap.insert(map::value_type(16, "gg"));
	//注意insert返回了一个键值对std::pair
	anmap.insert(map::value_type(23, "hello"));
	for (auto& x : anmap)
	{
		cout << x.first << " " << x.second << endl;
	}
	return 0;
}

#include
int main()
{
	std::multimapanmap;//允许关键码重复
	std::mapnamap;//不允许关键码重复
	//namap[23] = "yhping";
	//namap[16] = "gg";
	//namap[23] = "hello";
	std::pair::iterator, bool>it;
	it=namap.insert(map::value_type(23, "yhping"));
	it=namap.insert(map::value_type(16, "gg"));
	it=namap.insert(map::value_type(23, "hello"));
	if (it.second)
	{
		cout << it.first->first << " " << it.first->second << endl;
	}
	
	for (auto& x : namap)
	{
		cout << x.first << " " << x.second << endl;
	}
	return 0;
}

int main()
{
	std::mapsimap;
	simap["yhping"] = 12;
	simap["bh"] = 23;
	simap["mx"] = 18;
	string name;
	while (cin >> name, name != "end")
	{
		cout << simap[name] << endl;
	}
	return 0;
}

map的find函数
int main()
{
	std::mapsimap;
	simap["yhping"] = 12;
	simap["ljl"] = 23;
	simap["mx"] = 18;
	std::map::iterator it = simap.find("ljl");
	//从头到尾找一遍,找到就返回迭代器,没找到就返回end;
	if (it != simap.end())
	{
		cout << it->first << " " << it->second << endl;
	}
	else
	{
		cout << "not key" << endl;
	}
	return 0;
}

set有一定的查重功能,但是不能知道重复数据的个数
int main()
{
	std::setiset;
	int x;
	while (cin >> x, x != -1)
	{
		if (iset.count(x))
		{
			cout << "已经有了: " <
			iset.insert(x);
		}
	}
	return 0;
}

int main()
{
	mapimap;
	for (int i = 0; i < 1000; ++i)
	{
		int x = rand() % 1000;//ar;
		imap[x] += 1;
	}
	return 0;
}
lambda表达式的引入

原有c++想要对数据集进行排序需要用std::sort()

#include
#include
#include
using namespace std;
 
void main()
{
	int a[]={3,1,4,2,5};
	int i;
	int len=sizeof(a)/sizeof(int);//这里切记要除以sizeof(int)!
 
	sort(a ,a + len, greater());        //内置类型的由大到小排序
	for(i=0;i());		//内置类型的由小到大排序
	for(i=0;i 
#include
#include
int main()
{
 int array[] = { 4,1,8,5,3,7,0,9,2,6 };
 //默认排序是升序
 sort(array,sizeof(array)/array[0]);
 //降序
 sort(array,sizeof(array)/array[0],greater());
 return 0;
}

如果待排序数的类型是自定义类型,则用户自己定义;排序时的比较规则

struct Goods
{
	string _name;
	double _price;
};

struct Compare
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price <= gr._price;
	}
};

int main()
{
	Goods gds[] = { { "苹果", 2.1 }, { "香蕉", 3.0 }, { "橙子", 2.2 }, {"菠萝", 1.5} };
	sort(gds, gds + sizeof(gds) / sizeof(gds[0]), Compare());
	return 0;
}

随着C++语法的发展,人们开始觉得上面的写法太复杂了,每次为了实现一个algorithm算法, 都要重新去写一个类,如果每次比较的逻辑不一样,还要去实现多个类,特别是相同类的命名,这些都给编程者带来了极大的不便。因此,在C++11语法中出现了lambda表达式。

int main()
{
	Goods gds[] = { { "苹果", 2.1 }, { "相交", 3 }, { "橙子", 2.2 }, {"菠萝", 1.5} };
	sort(gds, gds + sizeof(gds) / sizeof(gds[0]), [](const Goods& L, const Goods& R)
		->bool
	{
		return L._price < R._price;
	});
	return 0;
}

lambda表达式语法

lambda表达式书写格式:
[capture-list] (parameters) mutable -> return-type {statement } ;

[capture-list] :捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。

(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略。

mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。这里的const修饰的是[]里面获取的,不能修饰[]获取引用的,可以修饰[var]或[=]创建副本的

->return_type:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。

{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。

注意:

在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为空。因此C++11中最简单的lambda函数为:[]{};
该lambda函数不能做任何事情。

int main()
{
    // 最简单的lambda表达式, 该lambda表达式没有任何意义
    [] {};

    // 省略参数列表和返回值类型,返回值类型由编译器推导为int
    int a = 3, b = 4;
    [=] {return a + 3; };

    // 省略了返回值类型,无返回值类型
    auto fun1 = [&](int c) {b = a + c; };
    fun1(10);
    cout << a << " " << b << endl;

    // 各部分都很完善的lambda函数
    auto fun2 = [=, &b](int c)->int {return b += a + c;};
    cout << fun2(10) << endl;

    // 复制捕捉x
    int x = 10;
    auto add_x = [x](int a)mutable{ x *= 2; return a + x;};
    cout << add_x(10) << endl;
    return 0;
}

template
struct my_plus
{
  _Ty operator()(_Ty a,_Ty b)const
  {
   return a+b;
  }

}
int main()
{
 auto f=[](int a,int b)-> int{return a+b;};
 my_plus myi;
 myi(12,23);
 int x=f(12,23);
 cout< 

通过上述例子可以看出,lambda表达式实际上可以理解为无名函数,该函数无法直接调用,如果想要直接调用,可借助auto将其赋值给一个变量。

int main()
{
	auto f1= [](int a)->int {return a; };
		//等价于
		//auto f=[](int a) {return a;}
	auto f = [](int a) {return a + 1; };
	//auto f = [](int a) {return { a,1 }; };//无法返回列表方案erro
	auto f2 = [](int a)->std::initializer_list {return { a,1 }; };//返回列表方案
	auto f3 = []() {return 1; };
	return 0;
}
捕获列表说明

[] :

int g_max = 10;

int add(int x, int y)
{
	return x + y;
}
int fun()
{
	int sum = 0;
	int num = 20;
	g_max = sum + num;
	//封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中
	//auto f = [](int a)->int {return a + sum; };//erro
	auto f = [sum](int a)->int {return a +sum; };
	auto f1 = [](int a)->int {return a + g_max; };//全局变量不需要捕获
	return f1(10);
}

int main()
{
	int a=fun();
	cout << a << endl;
    return 0;
}

[var]:表示值传递方式捕捉变量var,会创建副本

void fun()
{
	int x = 0;
	int y = 10;
	cout << &y << endl;
	//auto f = [y]()->int { y += 10; return y + 100; };//此时erro
	//此时y在lambda中只具备读的功能,也创建了副本;
	auto f = [y]()->int { cout << &y << endl; return y + 100; };
	f();
	cout <<&y<<" "<< y << endl;
	//创建副本
	auto f1 = [y]()mutable->int {y += 10; cout << y << endl; return y + 100; };
	f1();
	cout << y << endl;
}
int main()
{
	fun();
	return 0;
}

int g_max = 10;

int add(int x, int y)
{
	return x + y;
}
int fun()
{
	int sum = 0;
	int num = 20;
	g_max = sum + num;
	//封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中
	//auto f = [](int a)->int {return a + sum; };//erro
	auto f3 = [sum](int a)mutable->int {cout << sum << endl; return a + sum; };//
	f3(0);//sum只能读
	//auto f = [sum](int a)->int {sum += 10; return a + sum; };//erro
	//f(0);
	auto f = [sum](int a)mutable->int {sum += 10; cout << sum << endl;; return a + sum; };
	f(0);//里面的sum修改的话只能创建副本,写时拷贝技术,范围只在在上述lambda中
	cout << sum << endl;
	auto f1 = [](int a)->int {return a + g_max; };
	return f1(10);
}

int main()
{
	int a=fun();
	cout << a << endl;
    return 0;
}

[=]:表示值传递方式捕获所有父作用域中的变量(包括this),创建副本

[&var]:表示引用传递捕捉变量var

int g_max = 10;

int add(int x, int y)
{
	return x + y;
}
int fun()
{
	int sum = 0;
	int num = 20;
	g_max = sum + num;
	//封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中
	//auto f = [](int a)->int {return a + sum; };//erro
	auto f3 = [sum](int a)mutable->int {cout << sum << endl; return a + sum; };//
	f3(0);//sum只能读
	auto f = [&sum](int a)->int {sum += 10; return a + sum; };//这里相当于引用sum并不会重新创建sumf副本
	f(0);
	cout << sum << endl;
	//auto f = [sum](int a)mutable->int {sum += 10; cout << sum << endl;; return a + sum; };
	//f(0);//里面的sum修改的话只能创建副本,写时拷贝技术,范围只在在上述lambda中
	//cout << sum << endl;
	auto f1 = [](int a)->int {return a + g_max; };
	return f1(10);
}

int main()
{
	int a=fun();
	cout << a << endl;
    return 0;
}

[&]:表示引用传递捕捉所有父作用域中的所有变量(包括this)

int g_max = 10;

int add(int x, int y)
{
	return x + y;
}
int fun(int x)
{
	int sum = 0;
	int num = 20;
	g_max = sum + num;
	//封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中
	//auto f = [](int a)->int {return a + sum; };//erro
	//[&]在fun函数里面的局部变量可以直接在{}里面读,写
    auto f=[&](int a)->int {x=a; sum+=10; num=a+x; return a+sum;};
	
	return f(10);
}

int main()
{
	int a=fun(100);
	cout << a << endl;
    return 0;
}

[this]:表示值传递方式捕捉当前的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限。捕获this指针的目的是在lambda表达式中能够使用当前类的成员函数,和成员变量;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/875759.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号