查找算法---find运算,find_first_of的使用
一.find运算
假设有一个int型的vector对象,名为vec,我们想知道其中是否包含某个特定值。
解决这个问题最简单的方法时使用标准库提供的find运算:
1 // value we'll look for 2 int search_value = 42; 3 4 //call find to see if that value is present 5 vector<int>::const_iterator result = find(vec.begin() , vec.end() , search_value); 6 7 //report the result 8 cout<<"The value "<<search_value 9 <<(result == vec.end() ? " is not present" : "is present") 10 <<endl;
具体实现代码:
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 6 int main() 7 { 8 // value we'll look for 9 int search_value = 42; 10 int ival; 11 vector<int> vec; 12 13 while(cin>>ival) 14 vec.push_back(ival); 15 16 cin.clear(); 17 18 //call find to see if that value is present 19 vector<int>::const_iterator result = find(vec.begin() , vec.end() , search_value); 20 21 //report the result 22 cout<<"The value "<<search_value 23 <<(result == vec.end() ? " is not present" : "is present") 24 <<endl; 25 26 return 0; 27 }
类似地,由于指针的行为与作用在内置数组上的迭代器一样,因此也可以使用find来搜索数组:
1 int ia[6] = {27 , 210 , 12 , 47 , 109 , 83}; 2 int search_value = 83; 3 int *result = find(ia , ia + 6 , search_value); 4 cout<<"The value "<<search_value 5 <<(result == ia + 6 ? " is not present" : "is present") 6 <<endl;
如果需要传递一个子区间,则传递指向这个子区间的第一个元素以及最后一个元素的下一位置的迭代器(或指针)。
例如,在下面对find函数的调用中,只搜索了ia[1]和ia[2]:
//only search elements ia[1] and ia[2] int *result = find(ia + 1 , ia + 3 , search_value);
二.find_first_of的使用
除了find之外,标准库还定义了其他一些更复杂的查找算法。当中的一部分类似string类的find操作,其中一个是find_first_of函数。
这个算法带有两对迭代器参数来标记两端元素范围:第一段范围内查找与第二段范围中任意元素匹配的元素,然后返回一个迭代器,指向第一个匹配的元素。如果找不到匹配元素,则返回第一个范围的end迭代器。
假设roster1和roster2是两个存放名字的list对象,可使用find_first_of统计有多少个名字同时出现在这两个列表中:
1 size_t cnt = 0; 2 list<string>::iterator it = roster1.begin(); 3 4 // look in roster1 for any name also in roster2 5 while((it = find_first_of(it , roster1.end() , roster2.begin() , roster2.end())) != roster1.end()) 6 { 7 ++cnt; 8 // we got a match , increment it to look in the rest of roster1 9 ++it; 10 } 11 cout<<"Found "<<cnt 12 <<" names on both rosters "<<endl;
调 用find_first_of查找roster2中的每个元素是否与第一个范围内的元素匹配,也就是在it到roster1.end()范围内查找一个元 素。该函数返回此范围内第一个同时存在于第二个范围中的元素。在while的第一次循环中,遍历整个roster1范围。第二次以及后续的循环迭代则只考 虑roster1中尚未匹配的部分。
循环条件检查find_first_of的返回值,判断是否找到匹配的名字。如果找到一个匹配,则使计 数器加1,同时给it加1,使它指向roster1中的下一个元素。很明显可知,当不再有任何匹配时,find_first_of返回 roster1.end(),完成统计。
find_first_of,带有两对迭代器参数。每对迭代器中,两个参数的类型必须精确匹配,但不要求两对之间的类型匹配。特别是,元素可存储在不同类型的序列中,只要这两个序列的元素可以比较即可。
在 上述程序中,roster1和roster2的类型不必精确匹配:roster1可以使list对象,而roster2则可以使vector对象、 deque对象或者是其他后面要学到的序列。只要这两个序列的的元素可使用相等(==)操作符进行比较即可。如果roster1是list< string>对象,则roster2可以使vector<char*>对象,因为string标准库为string对象与char* 对象定义了相等(==)操作符。