反转数字的最有效方法
The most efficient way to reverse a number
我正在寻找一种有效的算法来反转数字,例如
输入:3456789
输出:9876543
在C++中,移位和位掩码有很多选择,但最有效的方法是什么?
我的平台:x86_64
数字范围:XXX-XXXXXXXXXX(3-9位(
编辑我输入的最后一个数字永远不会是零,所以不存在前导零的问题。
这样的东西会起作用:
#include <iostream>
int main()
{
long in = 3456789;
long out = 0;
while(in)
{
out *= 10;
out += in % 10;
in /= 10;
}
std::cout << out << std::endl;
return 0;
}
#include <stdio.h>
unsigned int reverse(unsigned int val)
{
unsigned int retval = 0;
while( val > 0)
{
retval = 10*retval + val%10;
val /= 10;
}
printf("returning - %d", retval);
return retval;
}
int main()
{
reverse(123);
}
您可以将数字转换为字符串,然后使用STL算法反转字符串。下面的代码应该有效:
long number = 123456789;
stringstream ss;
ss << number;
string numberToStr = ss.str();
std::reverse(numberToStr.begin(), numberToStr.end());
cout << atol(numberToStr.c_str());
您可能需要包括那些相关的头文件。我不确定这是否是最有效的方法,但STL算法通常非常有效。
static public int getReverseInt(int value) {
int resultNumber = 0;
for (int i = value; i != 0;) {
int d = i / 10;
resultNumber = (resultNumber - d) * 10 + i;
i = d;
}
return resultNumber;
}
我认为这将是在不使用asm
的情况下最快的方法。注意,d*10 + i
等效于i%10
,但速度快得多,因为模大约比乘法慢10倍
我测试了它,它比其他答案快了大约25%。
int ans=0;
int rev(int n)
{
ans=(ans+(n%10))*10; // using recursive function to reverse a number;
if(n>9)
rev(n/10);
}
int main()
{
int m=rev(456123); // m=32
return 0;
}
//Recursive method to find the reverse of a number
#include <bits/stdc++.h>
using namespace std;
int reversDigits(int num)
{
static int rev_num = 0;
static int base_pos = 1;
if(num > 0)
{
reversDigits(num/10);
rev_num += (num%10)*base_pos;
base_pos *= 10;
}
return rev_num;
}
int main()
{
int num = 4562;
cout << "Reverse " << reversDigits(num);
} ``
// recursive method to reverse number. lang = java
static void reverseNumber(int number){
// number == 0 is the base case
if(number !=0 ){
//recursive case
System.out.print(number %10);
reverseNumber(number /10);
}
}
这个解决方案效率不高,但它确实解决了问题,而且很有用。它为任何有符号整数(int、long、long-long等(返回long-long,为任何无符号整数(unsigned int、unsigned long、unsigned-long-leng等(返回unsigned long-long。
取决于编译器实现的字符类型可以是有符号的,也可以是无符号的。
#include <iostream>
#include <string>
#include <algorithm>
template <bool B>
struct SignedNumber
{
};
template <>
struct SignedNumber<true>
{
typedef long long type;
};
template <>
struct SignedNumber<false>
{
typedef unsigned long long type;
};
template <typename TNumber = int,
typename TResult = typename SignedNumber<std::is_signed<TNumber>::value>::type,
typename = typename std::void_t<std::enable_if_t<std::numeric_limits<TNumber>::is_integer>>>
TResult ReverseNumber(TNumber value)
{
bool isSigned = std::is_signed_v<TNumber>;
int sign = 1;
if (value < 0)
{
value *= -1;
sign = -1;
}
std::string str = std::to_string(value);
std::reverse(str.begin(), str.end());
return isSigned ? std::stoll(str) * sign : std::stoull(str) * sign;
}
int main()
{
std::cout << ReverseNumber(true) << std::endl; //bool -> unsigned long long
std::cout << ReverseNumber(false) << std::endl; //bool -> unsigned long long
std::cout << ReverseNumber('@') << std::endl; //char -> long long or unsigned long long
std::cout << ReverseNumber(46) << std::endl; //int -> long long
std::cout << ReverseNumber(-46) << std::endl; //int -> long long
std::cout << ReverseNumber(46U) << std::endl; //unsigned int -> unsigned long long
std::cout << ReverseNumber(46L) << std::endl; //long -> long long
std::cout << ReverseNumber(-46LL) << std::endl; //long long -> long long
std::cout << ReverseNumber(46UL) << std::endl; //unsigned long -> unsigned long long
std::cout << ReverseNumber(4600ULL) << std::endl; //unsigned long long -> unsigned long long
}
输出
1
0
64
64
-64
64
64
-64
64
64
测试此代码
https://repl.it/@JomaCorpFX/IntegerToStr#main.cpp
如果它是32位无符号整数(987654321是最大输入(,并且你有4GB的可用内存(就效率而言,你是指内存吗?(,
result=table[value]; // index 12345 has 54321, index 123 has 321
应该足够快。假设存储器在100ns时间或200个周期内被访问,并且整数平均为7位,则其他解决方案如下:
- 7次乘法
- 7添加
- 7模
- 7个分区
- 7次循环迭代,7次比较
若这些产生超过100纳秒/200个周期,那个么表会更快。例如,1个整数除法可以高达40个周期,所以我想这已经足够快了。如果重复输入,那么来自缓存的数据将具有更小的延迟。
但如果有数百万个反向操作并行,那么CPU计算绝对是比访问表更好的选择(使用矢量化计算循环+多线程可能会加速30x-100倍(。它每个核心有多个管道和多个核心。你甚至可以选择带有GPU的CUDA/OpenCL来获得额外的吞吐量,而这种与其他答案相反的解决方案看起来非常令人尴尬,因为1个输入独立于其他输入进行计算。
这是最简单的一个:
#include<iostream>
using namespace std;
int main()
{
int number, reversed=0;
cout<<"Input a number to Reverse: ";
cin>>number;
while(number!=0)
{
reversed= reversed*10;
reversed=reversed+number%10;
number=number/10;
}
cout<<"Reversed number is: "<<reversed<<endl;
}
- 在C++中初始化向量映射的最有效方法
- 将此布尔值传递给此函数的最有效方法是什么?
- 比较C++变量的最有效方法
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- 存储变量的更有效方法是什么?
- 确保套装新鲜度的有效方法
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 映射唯一值和重复值的有效方法.可以访问键或值的位置
- 在C++事务之间存储大量字符数据的有效方法
- 在unordered_multimap中精确迭代一次每个键的有效方法
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 检查两个向量是否并行的最有效方法
- 从浮点数中删除小数部分但保留类型的有效方法
- 传递非泛型函数的最有效方法是什么?
- 按升序打印矢量的所有元素直到它为空而没有重复项的最有效方法是什么?
- 创建字符串数组的有效方法
- 返回一个引用C++中另一个类对象的对象的有效方法
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 从std::map值中获取密钥的有效方法