简体   繁体   English

反转数字的最有效方法

[英]The most efficient way to reverse a number

I am looking for an efficient algorithm to reverse a number, eg我正在寻找一种有效的算法来反转数字,例如

Input: 3456789输入: 3456789

Output: 9876543输出: 9876543

In C++ there are plenty of options with shifting and bit masks but what would be the most efficient way ?在 C++ 中,有很多带有移位和位掩码的选项,但最有效的方法是什么?

My platform: x86_64我的平台:x86_64

Numbers range: XXX - XXXXXXXXXX (3 - 9 digits)号码范围:XXX - XXXXXXXXXX(3 - 9 位数字)

EDIT Last digit of my input will never be a zero so there is no leading zeros problem.编辑我输入的最后一位数字永远不会是零,所以没有前导零问题。

Something like this will work:像这样的事情会起作用:

#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);
}

You may convert the number to string and then reverse the string with STL algorithms.您可以将数字转换为字符串,然后使用 STL 算法反转字符串。 Code below should work:下面的代码应该工作:

 long number = 123456789;
 stringstream ss;
 ss << number;
 string numberToStr = ss.str();

 std::reverse(numberToStr.begin(), numberToStr.end());

 cout << atol(numberToStr.c_str());

You may need to include those relevant header files.您可能需要包含那些相关的头文件。 I am not sure whether it is the most efficient way, but STL algorithms are generally very efficient.我不确定这是否是最有效的方式,但 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;
}

I think this will be the fastest possible method without using asm .我认为这将是不使用asm的最快方法。 Note that d*10 + i is equivalent to i%10 but much faster since modulo is around 10 times slower than multiplication.请注意, d*10 + i等价于i%10但速度要快得多,因为模比乘法慢 10 倍左右。
I tested it and it is about 25 % faster than other answers.我测试了它,它比其他答案快了大约 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);
    }
}

This solution is not as efficient but it does solve the problem and can be useful.此解决方案效率不高,但确实解决了问题并且很有用。 It returns long long for any signed integer(int, long, long long, etc) and unsigned long long for any unsigned integer (unsigned int, unsigned long, unsigned long long, etc).它为任何有符号整数(int、long、long long 等)返回 long long,为任何无符号整数(unsigned int、unsigned long、unsigned long long 等)返回 unsigned long long。

The char type depends of compiler implementation can be signed or unsigned.取决于编译器实现的 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
}

Output输出

1
0
64
64
-64
64
64
-64
64
64

Test this code测试这段代码
https://repl.it/@JomaCorpFX/IntegerToStr#main.cpp https://repl.it/@JomaCorpFX/IntegerToStr#main.cpp

If it is 32-bit unsigned integer (987,654,321 being max input) and if you have 4GB free memory(by efficiency, did you mean memory too?),如果它是 32 位无符号整数(987,654,321 是最大输入),并且如果您有 4GB 可用内存(按效率来说,您也是指内存吗?),

result=table[value]; // index 12345 has 54321, index 123 has 321

should be fast enough.应该足够快。 Assuming memory is accessed at 100 ns time or 200 cycles and integer is 7 digits on average, other solutions have these:假设以 100 ns 时间或 200 个周期访问内存并且整数平均为 7 位,其他解决方案有这些:

  • 7 multiplications, 7 次乘法,
  • 7 adds, 7 添加,
  • 7 modulo, 7 模,
  • 7 divisions, 7个部门,
  • 7 loop iterations with 7 comparisons 7 次循环迭代,7 次比较

if these make more than 100 nanoseconds / 200 cycles, then table would be faster.如果这些超过 100 纳秒/200 个周期,那么 table 会更快。 For example, 1 integer division can be as high as 40 cycles, so I guess this can be fast enough.例如,1 个整数除法可以高达 40 个周期,所以我想这已经足够快了。 If inputs are repeated, then data will coming from cache will have even less latency.如果重复输入,那么来自缓存的数据将具有更少的延迟。

But if there are millions of reversing operations in parallel, then computing by CPU is absolutely the better choice (probably 30x-100x speedup using vectorized compute loop + multithreading) than accessing table.但是如果有数百万个并行的逆向操作,那么 CPU 计算绝对是比访问表更好的选择(使用矢量化计算循环 + 多线程可能会提高 30 倍-100 倍的加速)。 It has multiple pipelines per core and multiple cores.它有每个核心和多个核心的多个管道。 You can even choose CUDA/OpenCL with a GPU for extra throughput and this reversing solution from other answers look like perfectly embarrassingly parallelizable since 1 input computes independently of other inputs.您甚至可以选择带有 GPU 的 CUDA/OpenCL 以获得额外的吞吐量,并且这种从其他答案中得到的反向解决方案看起来非常令人尴尬地可并行化,因为 1 个输入独立于其他输入进行计算。

This is the easiest one:这是最简单的一种:

#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;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM