常用的泛型算法

本文介绍了C++标准库中的一些泛型算法,包括find、find_if、count、accumulate、find_first_of、fill、fill_n、sort、unique和count_if。详细解释了它们的功能、参数和使用场景,并提醒了在使用中需要注意的事项,如累加类型的匹配、安全写入和删除重复元素的方法。
摘要由CSDN通过智能技术生成


泛型算法大多在头文件algorithm

find

vector<int> a;
int val = 10
//find接受两个迭代器和要查找的值,如果找到,则返回该值对应的迭代器
//否则返回a.end()
auto it = find(a.begin(), a.end(), val);

find_if

vector<int> a;
int val = 10
//find_if 返回第一个满足条件的迭代器
//否则返回a.end()
auto it = find(a.begin(), a.end(), [](int a)->bool { return a == 1; });

count

vector<int> a;
int val = 10
//count 与find 的参数类型相同,统计两个迭代器之间的值val出现的次数
int s = count(a.begin(), a.end(), val);

accumulate

accumulate 带有三个形参。
头两个形参指定要累加的元素范围。第三个形参则是累加的初值。accumulate 函
数将它的一个内部变量设置为指定的初值,然后在此初值上累加输入范围 accumulate
用于指定累加起始值的第三个实参是必要的,因
为 accumulate 对将要累加的元素类型一无所知,因此,除此
之外,没有别的办法创建合适的起始值或者关联的类型。
accumulate 对要累加的元素类型一无所知,这个事实有两层含义。首先,调用
该函数时必须传递一个起始值,否则,accumulate 将不知道使用什么起始值。
其次,容器内的元素类型必须与第三个实参的类型匹配,或者可转换为第三个实
参的类型。在 accumulate 内部,第三个实参用作累加的起点;容器内的元素按
顺序连续累加到总和之中。因此,必须能够将元素类型加到总和类型上。

int main()
{
	vector<int> vec;

	for(int i = 0; i < 10; i++)
	{
		vec.push_back(i);	
	}
	
	//在100000的基础上进行累加
	int sum = accumulate(vec.begin(),vec.end(),100000);

	cout << sum << endl;
	return 0;
}

还可以进行字符串的累加

int main()
{
	string vec = "qweqwe";
	//可以进行字符串的拼接
	string sum = accumulate(vec.begin(),vec.end(),string("pppppp"));

	cout << sum << endl;
	return 0;
}

find_first_of

除了 find 之外,标准库还定义了其他一些更复杂的查找算法。当中的一部
分类似 string 类的 find 操作,其中一个是 find_first_of 函数。这个算法带有两对迭代器参数来标记两段元素范围,在第一段范围内查找与第二段范围中任意元素匹配的元素,然后返回一个迭代器,指向第一个匹配的元素。如果找不到元素,则返回第一个范围的 end 迭代器。

int main()
{
	srand(time(0));
	vector<int> vec1;
	vector<int> vec2;

	for(int i = 0; i < 1000; i++)
	{
		vec1.push_back(rand() % 100);
		vec2.push_back(rand() % 100);
	}

	auto it = find_first_of(vec1.begin(),vec1.end(),vec2.begin(),vec2.end());

	if(it != vec1.end())
	{
		cout << *it << endl;
	}
}

fill

fill 带有一对迭代器形参,用于指定要写入的范围,而所写的值是它的第三个
形参的副本。执行时,将该范围内的每个元素都设为给定的值。如果输入范围有
效,则可安全写入。这个算法只会对输入范围内已存在的元素进行写入操作

int main()
{
	srand(time(0));
	vector<int> vec1;

	for(int i = 0; i < 10; i++)
	{
		vec1.push_back(rand() % 100);
	}

	for(auto val:vec1)
	{
		cout << val << " ";
	}
	cout << endl;

	fill(vec1.begin(),vec1.end(),0);

	for(auto val:vec1)
	{
		cout << val << " ";
	}
	cout << endl;
}

fill_n

fill_n 函数带有的参数包括:一个迭代器、一个计数器以及一个值。该函
数从迭代器指向的元素开始,将指定数量的元素设置为给定的值。fill_n 函数
假定对指定数量的元素做写操作是安全的。初学者常犯的错误的是:在没有元素
的空容器上调用 fill_n 函数

这个 fill_n 函数的调用将带来灾难性的后果。我们指定要写入 10 个元
素,但这些元素却不存在——vec 是空的。其结果未定义,很可能导致严重的运行时错误。 对指定数目的元素做写入运算,或者写到目标迭代器的算法,都不检查目标的大小是否足以存储要写入的元素。

int main()
{
	srand(time(0));
	vector<int> vec1;

	for(int i = 0; i < 10; i++)
	{
		vec1.push_back(rand() % 100);
	}

	for(auto val:vec1)
	{
		cout << val << " ";
	}
	cout << endl;
	
	//fill使用
	fill_n(vec1.begin(),5,0);

	for(auto val:vec1)
	{
		cout << val << " ";
	}
	cout << endl;
}

sort

sort 内部采用快排算法.

int main()
{
	srand(time(0));
	vector<int> vec1;

	for(int i = 0; i < 100; i++)
	{
		vec1.push_back(rand() % 100);
	}

	sort(vec1.begin(),vec1.end());

	for(auto val:vec1)
	{
		cout << val << " ";
	}
	cout << endl;
}

unique

去除重复数据

如果要删除重复的项,必须使用容器操作,在本例中调用 erase 实现该功
能。这个函数调用从 it 指向的元素开始删除,直到 words 的最后一
个元素也删除掉为止。调用之后,words 存储输入的 8 个不相同的元素。
算法不直接修改容器的大小。如果需要添加或删除元素,则必
须使用容器操作。
值得注意的是,对没有重复元素的 vector 对象,调用 erase 也是安全的。
如果不存在重复的元素,unique 就会返回 words.end(),此时,调用 erase 的
两个实参值相同,都是 words.end()。两个迭代器相等这个事实意味着 erase 函
数要删除的范围是空的。删除一段空的范围没有任何作用,所以即使输入中没有
重复的元素,我们的程序仍然正确。

int main()
{
	srand(time(0));
	vector<int> vec1;

	for(int i = 0; i < 100; i++)
	{
		vec1.push_back(rand() % 100);
	}
	sort(vec1.begin(),vec1.end());

	//去除重复
	auto it = unique(vec1.begin(),vec1.end());

	vec1.erase(it,vec1.end());
}

count_if

按条件统计满足条件的元素的个数

int main()
{
	srand(time(0));
	vector<int> vec1;
	for(int i = 0; i < 100; i++)
	{
		vec1.push_back(i);
	}
	sort(vec1.begin(),vec1.end());
	//vector<int>::size_type vectmp = count_if(vec1.begin(),vec1.end(),comp());
	int a = count_if(vec1.begin(),vec1.end(),comp());

	//cout << vectmp << endl;
	cout << a << endl;
	return 0;
}

find_if

标准库定义了一个 find_if 函数。与 find 一样,find_if 函数带有一对迭代器形参,指定其操作的范围。与 count_if 一样,该函数还带有第三个形参,表明用于检查范围内每个元素的谓词函数。find_if 返回一个迭代器,指向第一个谓词函数返回非零值的元素。如果
这样的元素不存在,则返回第二个迭代器实参。使用 find_if 函数重写上述例题中统计长度大于 6 的单词个数的程序部分。

class comp
{
public:
	bool operator()(int a)
	{
		return a > 6;
	}
};

int main()
{
	srand(time(0));
	vector<int> vec1;
	for(int i = 0; i < 100; i++)
	{
		vec1.push_back(rand() % 100);
	}
	sort(vec1.begin(),vec1.end());

	auto it = find_if(vec1.begin(),vec1.end(),comp());

	cout << *it << endl;
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值