C++ 从字符串中修剪0

C++ 从字符串中修剪0,c++,string,substring,C++,String,Substring,假设我有像“0003443”这样的字符串,我们的目标是实现“3443”。我已经用SysEngin方法找出了0的数目,但是我想知道C++中最有效的方法。 你可以在中测试/运行这个代码。 代码 #include <iostream> #include <regex> #include <stdexcept> #include <chrono> time_t CurrentEpochMilliseconds() { using namespa

假设我有像“0003443”这样的字符串,我们的目标是实现“3443”。我已经用SysEngin方法找出了0的数目,但是我想知道C++中最有效的方法。

你可以在

中测试/运行这个代码。 代码

#include <iostream>
#include <regex>
#include <stdexcept>
#include <chrono>


time_t CurrentEpochMilliseconds()
{
    using namespace std::chrono;
    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}

std::string TrimZeros1(const std::string& number)
{
    std::regex regex(u8"[-+]?[0-9]{1,}", std::regex_constants::ECMAScript); 
    if(!std::regex_match(number, regex)) //Validating number format +XXXXX or -XXXXX or XXXXX
    {
        throw std::invalid_argument("Invalid parameter, it is not a number.");
    }

    std::string result = number;
    size_t pos = 0;
    if(result[0] == '+') 
    {
        result.erase(0,1);
    }
    if(result[0] == '-')
    {
        pos = 1;
    }

    while (result.size()>0 && result[pos]== '0') 
    {
        result.erase(pos,1); //Erase first char. Pos = pos, Count = 1
    }
    return (pos == 1 && result.size() ==1) || result.size() == 0 ? u8"0" : result; 
}

std::string TrimZeros2(const std::string& number)
{
    std::regex regex(u8"[-+]?[0-9]{1,}", std::regex_constants::ECMAScript);
    if(!std::regex_match(number, regex))
    {
        throw std::invalid_argument("Invalid parameter, it is not a number.");
    }

    int result = std::stoi(number);
    return std::to_string(result);
}

int main()
{
    std::cout<<u8"--- TrimZeros1"<< std::endl;
    std::cout<< TrimZeros1(u8"0003443") << std::endl;
    std::cout<< TrimZeros1(u8"0000123") << std::endl;
    std::cout<< TrimZeros1(u8"0000789") << std::endl;
    std::cout<< TrimZeros1(u8"0000000") << std::endl;

    std::cout<< TrimZeros1(u8"+0003443") << std::endl;
    std::cout<< TrimZeros1(u8"+0000123") << std::endl;
    std::cout<< TrimZeros1(u8"+0000789") << std::endl;
    std::cout<< TrimZeros1(u8"+0000000") << std::endl;

    std::cout<< TrimZeros1(u8"-0003443") << std::endl;
    std::cout<< TrimZeros1(u8"-0000123") << std::endl;
    std::cout<< TrimZeros1(u8"-0000789") << std::endl;
    std::cout<< TrimZeros1(u8"-0000000") << std::endl;

    std::cout <<std::endl;

    std::cout<<u8"--- TrimZeros2"<< std::endl;
    std::cout<< TrimZeros2(u8"0003443") << std::endl;
    std::cout<< TrimZeros2(u8"0000123") << std::endl;
    std::cout<< TrimZeros2(u8"0000789") << std::endl;
    std::cout<< TrimZeros2(u8"0000000") << std::endl;

    std::cout<< TrimZeros2(u8"+0003443") << std::endl;
    std::cout<< TrimZeros2(u8"+0000123") << std::endl;
    std::cout<< TrimZeros2(u8"+0000789") << std::endl;
    std::cout<< TrimZeros2(u8"+0000000") << std::endl;

    std::cout<< TrimZeros2(u8"-0003443") << std::endl;
    std::cout<< TrimZeros2(u8"-0000123") << std::endl;
    std::cout<< TrimZeros2(u8"-0000789") << std::endl;
    std::cout<< TrimZeros2(u8"-0000000") << std::endl;

    //std::cout<< TrimZeros2(u8"") << std::endl; //Error it is not a valid number value.

    std::cout <<std::endl;
    std::cout <<std::endl;

    int iterations = 10000;
    std::cout<<u8"--- Started - TrimZeros1 - Time Test"<< std::endl;
    time_t actual = CurrentEpochMilliseconds();
    for(int i = 0; i< iterations; i++)
    {
        TrimZeros1(u8"+0000000");
        TrimZeros1(u8"-0000000");
        TrimZeros1(u8"0000000");
        TrimZeros1(u8"+1111112");
        TrimZeros1(u8"-1111112");
        TrimZeros1(u8"1111112");
    }
    actual = CurrentEpochMilliseconds() - actual;
    std::cout << ("Elapsed seconds = " + std::to_string(actual / 1000.0) + "  ---  Elapsed milliseconds = " + std::to_string(actual) + "  ---  Elapsed minutes = " + std::to_string((actual / 1000.0) / 60.0)) << std::endl;
std::cout <<std::endl;
    std::cout <<std::endl;

    
    std::cout<<u8"--- Started - TrimZeros2 - Time Test"<< std::endl;
    actual = CurrentEpochMilliseconds();
    for(int i = 0; i< iterations; i++)
    {
        TrimZeros2(u8"+0000000");
        TrimZeros2(u8"-0000000");
        TrimZeros2(u8"0000000");
        TrimZeros2(u8"+1111112");
        TrimZeros2(u8"-1111112");
        TrimZeros2(u8"1111112");
    }
    actual = CurrentEpochMilliseconds() - actual;
    std::cout << ("Elapsed seconds = " + std::to_string(actual / 1000.0) + "  ---  Elapsed milliseconds = " + std::to_string(actual) + "  ---  Elapsed minutes = " + std::to_string((actual / 1000.0) / 60.0)) << std::endl;
    std::cout <<std::endl;
    std::cout <<std::endl;

    std::cout<< u8"Press enter to continue... ";
    std::cin.get();
    return EXIT_SUCCESS;
}
clang++-web/online

g++本地计算机

#include <iostream>
#include <regex>
#include <stdexcept>
#include <chrono>


time_t CurrentEpochMilliseconds()
{
    using namespace std::chrono;
    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}

std::string TrimZeros1(const std::string& number)
{
    std::regex regex(u8"[-+]?[0-9]{1,}", std::regex_constants::ECMAScript); 
    if(!std::regex_match(number, regex)) //Validating number format +XXXXX or -XXXXX or XXXXX
    {
        throw std::invalid_argument("Invalid parameter, it is not a number.");
    }

    std::string result = number;
    size_t pos = 0;
    if(result[0] == '+') 
    {
        result.erase(0,1);
    }
    if(result[0] == '-')
    {
        pos = 1;
    }

    while (result.size()>0 && result[pos]== '0') 
    {
        result.erase(pos,1); //Erase first char. Pos = pos, Count = 1
    }
    return (pos == 1 && result.size() ==1) || result.size() == 0 ? u8"0" : result; 
}

std::string TrimZeros2(const std::string& number)
{
    std::regex regex(u8"[-+]?[0-9]{1,}", std::regex_constants::ECMAScript);
    if(!std::regex_match(number, regex))
    {
        throw std::invalid_argument("Invalid parameter, it is not a number.");
    }

    int result = std::stoi(number);
    return std::to_string(result);
}

int main()
{
    std::cout<<u8"--- TrimZeros1"<< std::endl;
    std::cout<< TrimZeros1(u8"0003443") << std::endl;
    std::cout<< TrimZeros1(u8"0000123") << std::endl;
    std::cout<< TrimZeros1(u8"0000789") << std::endl;
    std::cout<< TrimZeros1(u8"0000000") << std::endl;

    std::cout<< TrimZeros1(u8"+0003443") << std::endl;
    std::cout<< TrimZeros1(u8"+0000123") << std::endl;
    std::cout<< TrimZeros1(u8"+0000789") << std::endl;
    std::cout<< TrimZeros1(u8"+0000000") << std::endl;

    std::cout<< TrimZeros1(u8"-0003443") << std::endl;
    std::cout<< TrimZeros1(u8"-0000123") << std::endl;
    std::cout<< TrimZeros1(u8"-0000789") << std::endl;
    std::cout<< TrimZeros1(u8"-0000000") << std::endl;

    std::cout <<std::endl;

    std::cout<<u8"--- TrimZeros2"<< std::endl;
    std::cout<< TrimZeros2(u8"0003443") << std::endl;
    std::cout<< TrimZeros2(u8"0000123") << std::endl;
    std::cout<< TrimZeros2(u8"0000789") << std::endl;
    std::cout<< TrimZeros2(u8"0000000") << std::endl;

    std::cout<< TrimZeros2(u8"+0003443") << std::endl;
    std::cout<< TrimZeros2(u8"+0000123") << std::endl;
    std::cout<< TrimZeros2(u8"+0000789") << std::endl;
    std::cout<< TrimZeros2(u8"+0000000") << std::endl;

    std::cout<< TrimZeros2(u8"-0003443") << std::endl;
    std::cout<< TrimZeros2(u8"-0000123") << std::endl;
    std::cout<< TrimZeros2(u8"-0000789") << std::endl;
    std::cout<< TrimZeros2(u8"-0000000") << std::endl;

    //std::cout<< TrimZeros2(u8"") << std::endl; //Error it is not a valid number value.

    std::cout <<std::endl;
    std::cout <<std::endl;

    int iterations = 10000;
    std::cout<<u8"--- Started - TrimZeros1 - Time Test"<< std::endl;
    time_t actual = CurrentEpochMilliseconds();
    for(int i = 0; i< iterations; i++)
    {
        TrimZeros1(u8"+0000000");
        TrimZeros1(u8"-0000000");
        TrimZeros1(u8"0000000");
        TrimZeros1(u8"+1111112");
        TrimZeros1(u8"-1111112");
        TrimZeros1(u8"1111112");
    }
    actual = CurrentEpochMilliseconds() - actual;
    std::cout << ("Elapsed seconds = " + std::to_string(actual / 1000.0) + "  ---  Elapsed milliseconds = " + std::to_string(actual) + "  ---  Elapsed minutes = " + std::to_string((actual / 1000.0) / 60.0)) << std::endl;
std::cout <<std::endl;
    std::cout <<std::endl;

    
    std::cout<<u8"--- Started - TrimZeros2 - Time Test"<< std::endl;
    actual = CurrentEpochMilliseconds();
    for(int i = 0; i< iterations; i++)
    {
        TrimZeros2(u8"+0000000");
        TrimZeros2(u8"-0000000");
        TrimZeros2(u8"0000000");
        TrimZeros2(u8"+1111112");
        TrimZeros2(u8"-1111112");
        TrimZeros2(u8"1111112");
    }
    actual = CurrentEpochMilliseconds() - actual;
    std::cout << ("Elapsed seconds = " + std::to_string(actual / 1000.0) + "  ---  Elapsed milliseconds = " + std::to_string(actual) + "  ---  Elapsed minutes = " + std::to_string((actual / 1000.0) / 60.0)) << std::endl;
    std::cout <<std::endl;
    std::cout <<std::endl;

    std::cout<< u8"Press enter to continue... ";
    std::cin.get();
    return EXIT_SUCCESS;
}

clang++本地计算机

#include <iostream>
#include <regex>
#include <stdexcept>
#include <chrono>


time_t CurrentEpochMilliseconds()
{
    using namespace std::chrono;
    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}

std::string TrimZeros1(const std::string& number)
{
    std::regex regex(u8"[-+]?[0-9]{1,}", std::regex_constants::ECMAScript); 
    if(!std::regex_match(number, regex)) //Validating number format +XXXXX or -XXXXX or XXXXX
    {
        throw std::invalid_argument("Invalid parameter, it is not a number.");
    }

    std::string result = number;
    size_t pos = 0;
    if(result[0] == '+') 
    {
        result.erase(0,1);
    }
    if(result[0] == '-')
    {
        pos = 1;
    }

    while (result.size()>0 && result[pos]== '0') 
    {
        result.erase(pos,1); //Erase first char. Pos = pos, Count = 1
    }
    return (pos == 1 && result.size() ==1) || result.size() == 0 ? u8"0" : result; 
}

std::string TrimZeros2(const std::string& number)
{
    std::regex regex(u8"[-+]?[0-9]{1,}", std::regex_constants::ECMAScript);
    if(!std::regex_match(number, regex))
    {
        throw std::invalid_argument("Invalid parameter, it is not a number.");
    }

    int result = std::stoi(number);
    return std::to_string(result);
}

int main()
{
    std::cout<<u8"--- TrimZeros1"<< std::endl;
    std::cout<< TrimZeros1(u8"0003443") << std::endl;
    std::cout<< TrimZeros1(u8"0000123") << std::endl;
    std::cout<< TrimZeros1(u8"0000789") << std::endl;
    std::cout<< TrimZeros1(u8"0000000") << std::endl;

    std::cout<< TrimZeros1(u8"+0003443") << std::endl;
    std::cout<< TrimZeros1(u8"+0000123") << std::endl;
    std::cout<< TrimZeros1(u8"+0000789") << std::endl;
    std::cout<< TrimZeros1(u8"+0000000") << std::endl;

    std::cout<< TrimZeros1(u8"-0003443") << std::endl;
    std::cout<< TrimZeros1(u8"-0000123") << std::endl;
    std::cout<< TrimZeros1(u8"-0000789") << std::endl;
    std::cout<< TrimZeros1(u8"-0000000") << std::endl;

    std::cout <<std::endl;

    std::cout<<u8"--- TrimZeros2"<< std::endl;
    std::cout<< TrimZeros2(u8"0003443") << std::endl;
    std::cout<< TrimZeros2(u8"0000123") << std::endl;
    std::cout<< TrimZeros2(u8"0000789") << std::endl;
    std::cout<< TrimZeros2(u8"0000000") << std::endl;

    std::cout<< TrimZeros2(u8"+0003443") << std::endl;
    std::cout<< TrimZeros2(u8"+0000123") << std::endl;
    std::cout<< TrimZeros2(u8"+0000789") << std::endl;
    std::cout<< TrimZeros2(u8"+0000000") << std::endl;

    std::cout<< TrimZeros2(u8"-0003443") << std::endl;
    std::cout<< TrimZeros2(u8"-0000123") << std::endl;
    std::cout<< TrimZeros2(u8"-0000789") << std::endl;
    std::cout<< TrimZeros2(u8"-0000000") << std::endl;

    //std::cout<< TrimZeros2(u8"") << std::endl; //Error it is not a valid number value.

    std::cout <<std::endl;
    std::cout <<std::endl;

    int iterations = 10000;
    std::cout<<u8"--- Started - TrimZeros1 - Time Test"<< std::endl;
    time_t actual = CurrentEpochMilliseconds();
    for(int i = 0; i< iterations; i++)
    {
        TrimZeros1(u8"+0000000");
        TrimZeros1(u8"-0000000");
        TrimZeros1(u8"0000000");
        TrimZeros1(u8"+1111112");
        TrimZeros1(u8"-1111112");
        TrimZeros1(u8"1111112");
    }
    actual = CurrentEpochMilliseconds() - actual;
    std::cout << ("Elapsed seconds = " + std::to_string(actual / 1000.0) + "  ---  Elapsed milliseconds = " + std::to_string(actual) + "  ---  Elapsed minutes = " + std::to_string((actual / 1000.0) / 60.0)) << std::endl;
std::cout <<std::endl;
    std::cout <<std::endl;

    
    std::cout<<u8"--- Started - TrimZeros2 - Time Test"<< std::endl;
    actual = CurrentEpochMilliseconds();
    for(int i = 0; i< iterations; i++)
    {
        TrimZeros2(u8"+0000000");
        TrimZeros2(u8"-0000000");
        TrimZeros2(u8"0000000");
        TrimZeros2(u8"+1111112");
        TrimZeros2(u8"-1111112");
        TrimZeros2(u8"1111112");
    }
    actual = CurrentEpochMilliseconds() - actual;
    std::cout << ("Elapsed seconds = " + std::to_string(actual / 1000.0) + "  ---  Elapsed milliseconds = " + std::to_string(actual) + "  ---  Elapsed minutes = " + std::to_string((actual / 1000.0) / 60.0)) << std::endl;
    std::cout <<std::endl;
    std::cout <<std::endl;

    std::cout<< u8"Press enter to continue... ";
    std::cin.get();
    return EXIT_SUCCESS;
}

这将对您有所帮助,但我想知道最理想的方法。您会发现“最理想”的定义并不明确。你是说最快的?如果是,数据是什么样子的?你开过一次吗?1e6次?平均有多少个零?有多少字符串没有前导零?您的主机的性能如何?您想使用AVX指令吗?如果是,是哪种指令?另一个可选选项可能是最短代码。“最优化”可能是首先不生成带有不需要的前导零的字符串。然后,不需要前导零删除,在这种情况下,前导零删除步骤是无操作的,因此效率最高。找到零的数量,然后使用
substr
对我来说是最佳的。你能想出更理想的流程吗?当然,这完全取决于你所说的“最优”是什么意思。我觉得,当初学者在没有定义任何术语的情况下问什么是最优化的、最有效的或最好的,那仅仅是因为他们对自己的代码缺乏信心。这就像他们认为有一些专家知道的秘密诀窍,但他们不知道。如果你能展示时间比较,那就太好了。顺便说一句,我们的第二个trim函数需要一个条件,即字符串在long范围内,这可能不是真的。添加时间比较、数字验证。