我正在寻找一种有效的算法来反转一个数字,例如
输入: 3456789
输出: 9876543
在 C++ 中,有很多带有移位和位掩码的选项,但最有效的方法是什么?
我的平台:x86_64
数字范围:XXX - XXXXXXXXXX(3 - 9 位)
编辑 我输入的最后一位数字永远不会为零,因此不存在前导零问题。
我正在寻找一种有效的算法来反转一个数字,例如
输入: 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 算法通常非常有效。
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;
}
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%。
//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 long 等)返回 unsigned long long。
char 类型取决于编译器实现,可以是有符号的或无符号的。
#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
如果它是 32 位无符号整数(最大输入为 987,654,321)并且如果您有 4GB 可用内存(按效率,您是指内存吗?),
result=table[value]; // index 12345 has 54321, index 123 has 321
应该足够快。假设以 100 ns 时间或 200 个周期访问内存并且整数平均为 7 位,其他解决方案有:
如果这些时间超过 100 纳秒/200 个周期,那么表格会更快。例如,1 个整数除法可以高达 40 个周期,所以我想这可能足够快。如果重复输入,那么来自缓存的数据将具有更少的延迟。
但是如果有数百万个并行的反向操作,那么 CPU 计算绝对是比访问表更好的选择(使用矢量化计算循环 + 多线程可能会提高 30 倍至 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;
}