如何在有效和快速的方式添加前缀号码和删除
How to on efficient and quick way add prefix to number and remove?
如何以高效快捷的方式添加前缀到号码和删除?(数字可以是任意位数,数字没有限制)我有一个数字,例如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;
- 如何在c++中为模板函数实例创建快捷方式
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 如何以编程方式查找加载的共享库的版本?
- 如果 QApplication 执行延迟,QWebEngineView 在加载内容时会以静默方式失败
- 如何以编程方式知道Adobe Reader完成了加载文件
- RedHatLinux :是否可以以编程方式加载 libcert.so 共享对象
- C++成员函数定义类前缀快捷方式(也是模板)
- 加载到内存的文件的大小远大于其磁盘大小?!!任何压缩方式
- 在C++命名空间中,当在头中声明的非成员子例程前面加前缀时,“static”限定符是否有任何作用
- 以更固定的方式将双精度加到双精度
- 解决std::showbase不加零前缀的问题
- 我是否可以以可以在加载时删除 dll 的方式加载它?
- 为什么SDL不加载我的图像时,主应用程序通过快捷方式访问
- OpenGL -正确的方式来加载多面
- 如何在有效和快速的方式添加前缀号码和删除
- 如何使用L前缀作为未加引号的字符串
- 改变加载资源的方式
- 如何从文本文件中只加载某些行,这取决于它们在C和c++中的开始方式