如何将std :: string转换为小写?

我想将std::string转换为小写。 我知道函数tolower() ,可是在过去我遇到了这个函数的问题,而且由于使用std::string须要迭代每一个字符,因此它几乎不理想。 html

有没有一种方法能够100%的时间运做? ios


#1楼

据我所知,Boost库的性能很是糟糕。 我已经测试了他们的unordered_map到STL,平均慢了3倍(最好的状况2,最差的是10次)。 此算法看起来也过低了。 算法

所不一样的是如此之大,我相信任何另外,你须要作的tolower使其等于提升“您的需求”会比升压方式更快ide

我已经在Amazon EC2上完成了这些测试,所以在测试过程当中性能会有所不一样,但您仍然能够理解。 函数

./test
Elapsed time: 12365milliseconds
Elapsed time: 1640milliseconds
./test
Elapsed time: 26978milliseconds
Elapsed time: 1646milliseconds
./test
Elapsed time: 6957milliseconds
Elapsed time: 1634milliseconds
./test
Elapsed time: 23177milliseconds
Elapsed time: 2421milliseconds
./test
Elapsed time: 17342milliseconds
Elapsed time: 14132milliseconds
./test
Elapsed time: 7355milliseconds
Elapsed time: 1645milliseconds

-O2就是这样的: oop

./test
Elapsed time: 3769milliseconds
Elapsed time: 565milliseconds
./test
Elapsed time: 3815milliseconds
Elapsed time: 565milliseconds
./test
Elapsed time: 3643milliseconds
Elapsed time: 566milliseconds
./test
Elapsed time: 22018milliseconds
Elapsed time: 566milliseconds
./test
Elapsed time: 3845milliseconds
Elapsed time: 569milliseconds

资源: 性能

string str;
bench.start();
for(long long i=0;i<1000000;i++)
{
    str="DSFZKMdskfdsjfsdfJDASFNSDJFXCKVdnjsafnjsdfjdnjasnJDNASFDJDSFSDNJjdsanjfsdnfjJNFSDJFSD";
    boost::algorithm::to_lower(str);
}
bench.end();

bench.start();
for(long long i=0;i<1000000;i++)
{
    str="DSFZKMdskfdsjfsdfJDASFNSDJFXCKVdnjsafnjsdfjdnjasnJDNASFDJDSFSDNJjdsanjfsdnfjJNFSDJFSD";
    for(unsigned short loop=0;loop < str.size();loop++)
    {
        str[loop]=tolower(str[loop]);
    }
}
bench.end();

我想我应该在专用机器上进行测试可是我将使用这个EC2因此我真的不须要在个人机器上测试它。 测试


#2楼

若是字符串包含ASCII范围以外的UTF-8字符,则boost :: algorithm :: to_lower将不会转换这些字符。 当涉及UTF-8时,最好使用boost :: locale :: to_lower。 请参阅http://www.boost.org/doc/libs/1_51_0/libs/locale/doc/html/conversions.html spa


#3楼

这是Stefan Mai的回应的后续行动:若是您想将转换结果放在另外一个字符串中,则须要在调用std::transform以前预先分配其存储空间。 因为STL将转换后的字符存储在目标迭代器中(在循环的每次迭代中将其递增),所以目标字符串将不会自动调整大小,而且存在内存占用风险。 code

#include <string>
#include <algorithm>
#include <iostream>

int main (int argc, char* argv[])
{
  std::string sourceString = "Abc";
  std::string destinationString;

  // Allocate the destination space
  destinationString.resize(sourceString.size());

  // Convert the source string to lower case
  // storing the result in destination string
  std::transform(sourceString.begin(),
                 sourceString.end(),
                 destinationString.begin(),
                 ::tolower);

  // Output the result of the conversion
  std::cout << sourceString
            << " -> "
            << destinationString
            << std::endl;
}

#4楼

//You can really just write one on the fly whenever you need one.
#include <string>
void _lower_case(std::string& s){
for(unsigned short l = s.size();l;s[--l]|=(1<<5));
}
//Here is an example.
//http://ideone.com/mw2eDK

#5楼

Boost的另外一种选择是POCO(pocoproject.org)。

POCO提供两种变体:

  1. 第一个变体制做副本而不更改原始字符串。
  2. 第二个变体将原始字符串更改成适当位置。
    “就地”版本的名称中始终包含“InPlace”。

两个版本以下所示:

#include "Poco/String.h"
using namespace Poco;

std::string hello("Stack Overflow!");

// Copies "STACK OVERFLOW!" into 'newString' without altering 'hello.'
std::string newString(toUpper(hello));

// Changes newString in-place to read "stack overflow!"
toLowerInPlace(newString);