C++STL容器及其他类型使用中的一些问题

本文详细探讨了C++ STL中关于删除向量重复元素的三种方法:Unique、Set和Map,以及它们的优缺点。同时,讲解了String.substr()的用法,set、map、unordered_map的有序性和无序性,char*与char[]的区别,以及递归执行顺序和返回值的影响。此外,还讨论了for循环嵌套、char型算术运算、map容器的erase方法、字符串与整数的转换,并提供了关于输入流结尾判断的提示。
摘要由CSDN通过智能技术生成

1.Vector删除重复元素

        源代码:https://github.com/AnkangH/CSDN/tree/master/STL
        这里介绍分为三种方法,Unique,Set和Map方法。Unique方法要求先对输入数组进行排序,删除重复元之后会改变相对顺序,输出为有序序列;Set方法因此储存结构有序,因此结果也为有序序列;Map方法可不改变原数组的相对顺序。
        不要尝试使用双指针遍历数组的方法。如果使用索引遍历,那么只能确定哪些项重复而不能删除,因为erase使用迭代器作为参数,否则只能将数组移动至数组末尾,使用pop_back()删除。对于每一个数组元素都要遍历数组该项之后的元素,时间复杂度至少是O(N*N)。并且要注意,因为删除一个重复项后,数组的大小变化了,因此索引需要对应修改。如果是迭代器,那么要注意,erase(itr)之后,itr被释放了。因此这种方法太繁琐,不推荐使用。

1.1Unique方法

        itr unique(itr1,itr2);是unique函数的原形,itr1和itr2是迭代器std::itreator,指代首尾位置,[itr1,itr2)包含itr1不包含itr2,unique将输入数组中的重复元素放到数组的末尾,itr返回指向数组第一个重复元素的迭代器。所以对于模版类vector,可以使用来unique和erase来删除重复元素,但是注意,unique只比较相邻项,如果重复元素不相邻,则不会认为是重复元素。因此unique只能用于排序元素的重复处理。

arr.erase(unique(arr.begin(),arr.end()),arr.end());
{    
    sort(arr.begin(), arr.end());//先将输入序列排序
    arr.erase(unique(arr.begin(), arr.end()), arr.end());//删除序列末尾的重复项
}

1.2 Set方法

        将原输入序列全部放入Set中,利用Set的互异性,删除重复元。将Set中的元素全部取出即为删除重复元后的序列,因为Set有序,且无法获取Set中每个元素在原输入序列中的相对位置,因此输出序列是有序的。

set<int> auxSet;//辅助集合
for (auto p : arr)
    auxSet.insert(p);//输入序列入辅助集合
arr.clear();//输入序列清空
for (auto p : auxSet)
    arr.push_back(p);//输入序列出辅助集合

1.3 Map方法

        利用一个哈希表储存当前项是否出现过,遍历原输入序列,查表,若未出现,放入表中并向后继续遍历,否则删除该元素。因为erase()需要使用迭代器作为参数,因此这里使用迭代器遍历原输入序列。注意erase()的特性,删除的迭代器被释放,返回原序列中删除项之后的迭代器。因此删除重复项时,给迭代器赋值erase()的返回值即可使遍历继续。

map<int, int> exist;//辅助哈希表
auto itr = arr.begin();//迭代器遍历起点
while (itr != arr.end())//遍历输入序列
{
	if (exist.count(*itr) == 0)//表中无该项
	{
	    exist[*itr]++;//入表
	    itr++;//迭代器指向下一个 遍历继续
	}
	else//表中有该项
	{
	    itr = arr.erase(itr);//删除该项 迭代器指向下一项 遍历继续
}

1.4测试

void deleteDupVector(vector<int>& arr, method m)
{
	if (m == setFunc)//使用Set<>
	{
		set<int> auxSet;
		for (auto p : arr)
			auxSet.insert(p);
		arr.clear();
		for (auto p : auxSet)
			arr.push_back(p);
	}
	else if (m == uniqueFunc)//使用Unique()
	{
		sort(arr.begin(), arr.end());
		arr.erase(unique(arr.begin(), arr.end()), arr.end());
	}
	else if (m == mapFunc)//使用Map<>
	{
		map<int, int> exist;
		auto itr = arr.begin();
		while (itr != arr.end())
		{
			if (exist.count(*itr) == 0)
			{
				exist[*itr]++;
				itr++;
			}
			else
			{
				itr = arr.erase(itr);
			}
		}
	}
    else
        cout<<"method illegal."<<endl;
}
#include<iostream>      //for cout endl
#include<set>           //for set<>
#include<vector>        //for vector<>
#include<algorithm>     //for sort()
#include<map>           //for map<>
using namespace std;
enum method{setFunc,uniqueFunc,mapFunc};//定义方法的枚举类型
void deleteDupVector(vector<int>&arr, method m);//arr待处理序列 m处理方法
int main()
{
	vector<int>arr{ 23,45,21,21,66,12,3,3,3,1,6,32,23 };
	cout << "Original Vector:" << endl;
	for (auto p : arr)
		cout << p << " ";
	cout << endl;
	cout << "Delete dup via Set:" << endl;
	deleteDupVector(arr, setFunc);
	for (auto p : arr)
		cout << p << " ";
	cout << endl;
	arr={ 23,45,21,21,66,12,3,3,3,1,6,32,23 };
	cout << "Delete dup via Unique:" << endl;
	deleteDupVector(arr, uniqueFunc);
	for (auto p : arr)
		cout << p << " ";
	cout << endl;
	arr = { 23,45,21,21,66,12,3,3,3,1,6,32,23 };
	cout << "Delete dup via Map:" << endl;
	deleteDupVector(arr,
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值