如何在有效和快速的方式添加前缀号码和删除

How to on efficient and quick way add prefix to number and remove?

本文关键字:方式添 加前缀 号码 删除 有效      更新时间:2023-10-16

如何以高效快捷的方式添加前缀到号码和删除?(数字可以是任意位数,数字没有限制)我有一个数字,例如122121,我想在开头添加数字9为9122121,之后我需要删除数字中的第一个数字。我已经分成了向量,推前数字(在本例中为9)和从数字创建数字(迭代乘以10)。有没有更有效的方法?

如果你想要效率,不要使用数字以外的任何东西,不要使用向量、字符串等。在你的例子中:

#include <iostream>
unsigned long long add_prefix( unsigned long long number, unsigned prefix )
{
    // if you want the example marked (X) below to print "9", add this line:
    if( number == 0 ) return prefix;
    // without the above, the result of (X) would be "90"
    unsigned long long tmp = ( number >= 100000 ) ? 1000000 : 10;
    while( number >= tmp ) tmp *= 10;
    return number + prefix * tmp;
}
int main()
{
    std::cout << add_prefix( 122121, 9 ) << std::endl; // prints 9122121
    std::cout << add_prefix( 122121, 987 ) << std::endl; // prints 987122121
    std::cout << add_prefix( 1, 9 ) << std::endl; // prints 91
    std::cout << add_prefix( 0, 9 ) << std::endl; // (X) prints 9 or 90
}

,但要注意溢出。如果没有溢出,上面的代码甚至适用于多位数前缀。我希望你能想出反向算法来删除前缀。


Edited:正如Andy Prowl所指出的,人们可以将0解释为"没有数字",因此前缀不应该在后面跟数字0。但我猜这取决于OPs用例,所以我相应地编辑了代码。

您可以使用floor(log10(number)) + 1来计算位数。所以代码看起来像:

int number = 122121;
int noDigits = floor(log10(number)) + 1;
//Add 9 in front
number += 9*pow(10,noDigits);
//Now strip the 9
number %= pow(10,noDigits);

我希望我做的都是对的;)

我将提供一个使用二分搜索的答案和目前提供的答案的一个小基准。

二叉搜索

下面的函数使用二进制查找查找所需数字的位数,并将所需数字添加到其前面。

int addPrefix(int N, int digit) {
    int multiplier = 0;
    // [1, 5]
    if(N <= 100000) {
        // [1, 3]
        if(N <= 1000) {
            //[1, 2]
            if(N <= 100) {
                //[1, 1]
                if(N <= 10) {
                    multiplier = 10;
                //[2, 2]
                } else {
                    multiplier = 100;
                }
            //[3, 3]
            } else {
                multiplier = 1000;
            }
        //[4, 4]
        } else if(N <= 10000) {
            multiplier = 10000;
        //[5, 5]
        } else {
            multiplier = 100000;
        }
    //[6, 7]
    } else if(N <= 10000000) {
        //[6, 6]
        if(N <= 1000000) {
            multiplier = 1000000;
        //[7, 7]
        } else {
            multiplier = 10000000;
        }
    //[8, 9]
    } else {
        //[8, 8]
        if(N <= 100000000) {
            multiplier = 100000000;
        //[9, 9]
        } else {
            multiplier = 1000000000;
        }
    }
    return N + digit * multiplier;
}

太啰嗦了。但是,它在最多4次比较中找到int范围内的数字的位数。

基准

我创建了一个小的基准测试,运行每个提供的算法4.5亿次迭代,每个确定的数字数5000万次迭代。

int main(void) {
    int i, j, N = 2, k;
    for(i = 1; i < 9; ++i, N *= 10) {
        for(j = 1; j < 50000000; ++j) {
            k = addPrefix(N, 9);
        }
    }
    return 0;
}
结果:

+-----+-----------+-------------+----------+---------+
| run | Alexander | Daniel Frey | kkuryllo | W.B.    |
+-----+-----------+-------------+----------+---------+
| 1st |    2.204s |      3.983s |   5.145s | 23.216s |
+-----+-----------+-------------+----------+---------+
| 2nd |    2.189s |      4.044s |   5.081s | 23.484s |
+-----+-----------+-------------+----------+---------+
| 3rd |    2.197s |      4.232s |   5.043s | 23.378s |
+-----+-----------+-------------+----------+---------+
| AVG |    2.197s |      4.086s |   5.090s | 23.359s |
+-----+-----------+-------------+----------+---------+

您可以在这里找到此Gist中使用的源代码。

如何使用boost的词法强制转换?这样你就不用自己做迭代了

http://www.boost.org/doc/libs/1_53_0/doc/html/boost_lexical_cast.html

你可以把数字放在std::string中并使用insert和delete操作,但这可能有点过头了

%首先找出比你的数字大的10的最大次幂。然后乘以这个数,再加上你的数字

例如:

int x;
int addition;
int y = 1;
while (y <= x)
{
    y *= 10;
}
x += addition * y;

我没有测试这段代码,所以只是作为一个例子…我也不太明白你的其他指示,你需要澄清一下。

edit好的,我想我理解你有时也想删除第一个数字。您可以使用类似的方法来完成此操作。

int x;
int y = 1;
while (y <= x*10)
{
    y *= 10;
}
x %= y;