transform函数转换字符串string的大小写

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tham_/article/details/51201249

首先看一下transform函数的用户手册:

template < class InputIterator, class OutputIterator, class UnaryOperator >
  OutputIterator transform ( InputIterator first1, InputIterator last1,
                             OutputIterator result, UnaryOperator op );
template < class InputIterator1, class InputIterator2,
           class OutputIterator, class BinaryOperator >
  OutputIterator transform ( InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, OutputIterator result,
                             BinaryOperator binary_op );
使用案例:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int main()
{
	string str = "Hello World!";
	transform(str.begin(), str.end(), str.begin(),tolower);
	cout << str << endl;
}
在VS下这个程序编译运行都很正常,但是在G++下编译就不是那么回事了。今天写这篇博客的目的就是解决这里出现的错误。

G++编译错误信息如下

tham@root-laptop:~/Desktop$ g++ -o test test.cc
test.cc: In function ‘int main()’:
test.cc:9: error: no matching function for call to
     ‘transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>,
	 std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*,
	 std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
	  __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>,
	  std::allocator<char> > >, <unresolved overloaded function type>)’
最后两句话可以看出,是重载函数出现了错误。请教Google,发现tolower/toupper函数有两个定义:
int std::toupper(int); // from <cctype>

以及 

template <class chart> 
               charT std::toupper(charT, const locale&);// from <locale>

编译器并不能分辨两个函数的区别,导致编译错误。此时我们便要告诉编译器,使用哪一个函数,看例子:

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int main()
{
	string str = "Hello World!";
	transform(str.begin(), str.end(), str.begin(), (int(*)(int)) tolower);
	cout << str << endl;
}
其中,(int(*)(int))为函数指针类型,告诉编译器要调用“输入参数是一个int,返回值也是int”的函数。如果不了解函数指针的用法,可以请教Google,这里不再赘述。

transform函数的作用是:将某操作应用于指定范围的每个元素。transform函数有两个重载版本:
transform(first,last,result,op);//first是容器的首迭代器,last为容器的末迭代器,result为存放结果的容器,op为要进行操作的一元函数对象或sturct、class。

transform(first1,last1,first2,result,binary_op);//first1是第一个容器的首迭代器,last1为第一个容器的末迭代器,first2为第二个容器的首迭代器,result为存放结果的容器,binary_op为要进行操作的二元函数对象或sturct、class。
注意:第二个重载版本必须要保证两个容器的元素个数相等才行,否则会抛出异常
看一个例子:利用transform函数将一个给定的字符串中的小写字母改写成大写字母,并将结果保存在一个叫second的数组里,原字符串内容不变。
我们只需要使用transform的第一个重载函数,当然我们也可以使用for_each函数来完成再copy几次就行了,现在来看一下代码:

#include <iostream>
#include <algorithm>
using namespace std;
char op(char ch)
{
    if(ch>='A'&&ch<='Z')
        return ch+32;
    else
        return ch;
}
int main()
{
    string first,second;
    cin>>first;
    second.resize(first.size());
    transform(first.begin(),first.end(),second.begin(),op);
    cout<<second<<endl;
    return 0;
}
再看一个例子:给你两个vector向量(元素个数相等),请你利用transform函数将两个vector的每个元素相乘,并输出相乘的结果。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void print(int &elem){cout<<elem<<" ";}
int op(int a,int b){return a*b;}
int main()
{
    vector <int> A,B,SUM;
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        int t;
        cin>>t;
        A.push_back(t);
    }
    for(int i=0;i<n;i++)
    {
        int t;
        cin>>t;
        B.push_back(t);
    }
    SUM.resize(n);
    transform(A.begin(),A.end(),B.begin(),SUM.begin(),op);
    for_each(SUM.begin(),SUM.end(),print);
    return 0;
}
输入:
5
1 2 3 4 5
5 4 3 2 1
输出:
5 8 9 8 5

网上复制的例子

#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
class Print
{
	public:
    void operator () (int val)
    {
        cout << val << " " ;
    }
};
int main()
{
    int arr1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9} ;
    vector<int> vec1(arr1, arr1 + sizeof arr1 / sizeof (int)) ;
    vector<int> vec2(9, 0) ;
    //    transform(beg, end, dest, unaryOp) ;
    //    操作前:[beg,end)标示输入序列.dest是目标迭代器.unaryOp是一元函数对象.
    //    操作后:对[beg,end)中每个元素应用unaryOp操作并将结果复制到dest迭代器所在的容器中.
    //    返回值:返回目标容器中被写入的最后一个位置的下一个迭代器.
    //    备注:        [dest,...)必须能够存储[beg,end)中的全部元素.否则将抛出异常.
    transform(vec1.begin(), vec1.end(), vec2.begin(), bind2nd(plus<int> (), 1000)) ;
    for_each(vec2.begin(), vec2.end(), Print()) ;
    //  transform(beg, end, beg2, dest, binaryOp) ;
    //  操作前:[beg,end)标示输入序列.[beg2,...)标示输入序列.dest是目标迭代器..binaryOp是二元函数对象.
    //  操作后:[beg,end)序列中的元素依次作为二元操作的第一个实参.
    //         [beg2,...)序列中的元素依次作为二元操作的第二个实参.将运算结果依次复制到dest迭代器所在的容器中.
    //    返回值:返回目标容器中被写入的最后一个元素的下一个位置的迭代器.
    //    备注: [beg2,...)必须能够存储[beg,end)中的全部元素.
    //          [dest,...)必须能够存储[beg,end)中的全部元素.否则将抛出异常
    vector<int> vec3(18, 1) ;
    transform(vec1.begin(), vec1.end(), vec2.begin(), vec3.begin(), multiplies<int> ()) ;
    for_each(vec3.begin(), vec3.end(), Print()) ;
    return 0 ;
}


猜你喜欢

转载自blog.csdn.net/tham_/article/details/51201249
今日推荐