扭转数字的最有效方法

时间:2013-03-12 06:52:37

标签: c++ performance algorithm optimization

我正在寻找一种有效的算法来反转一个数字,例如

输入: 3456789

输出 9876543

在C ++中,有很多选项可以使用移位和位掩码,但最有效的方法是什么?

我的平台:x86_64

数字范围:XXX - XXXXXXXXXX(3 - 9位)

修改 我的输入的最后一位数字永远不会为零,因此没有前导零问题。

10 个答案:

答案 0 :(得分:11)

这样的事情会起作用:

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

答案 1 :(得分:3)

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

答案 2 :(得分:3)

您可以将数字转换为字符串,然后使用STL算法反转字符串。下面的代码应该有效:

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

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

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

您可能需要包含这些相关的头文件。我不确定它是否是最有效的方法,但STL算法通常非常有效。

答案 3 :(得分:0)

CLASSPATH

答案 4 :(得分: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%。

答案 5 :(得分: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); 
    } ``

答案 6 :(得分:0)

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

答案 7 :(得分:0)

此解决方案效率不高,但确实解决了问题并且很有用。 它对任何有符号整数(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

测试此代码
https://repl.it/@JomaCorpFX/IntegerToStr#main.cpp

答案 8 :(得分:0)

如果它是 32 位无符号整数(987,654,321 是最大输入),并且如果您有 4GB 可用内存(根据效率,您也是指内存吗?),

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

应该足够快。假设以 100 ns 时间或 200 个周期访问内存,并且整数平均为 7 位,其他解决方案有这些:

  • 7 次乘法,
  • 7 添加,
  • 7 模,
  • 7 个部门,
  • 7 次循环迭代,7 次比较

如果这些超过 100 纳秒/200 个周期,那么 table 会更快。例如,1 个整数除法可以高达 40 个周期,所以我想这已经足够快了。如果重复输入,那么来自缓存的数据将有更少的延迟。

但如果有数百万个并行的逆向操作,那么通过 CPU 计算绝对是比访问表更好的选择(使用矢量化计算循环 + 多线程可能会提高 30-100 倍的加速)。它有每个核心和多个核心的多个管道。您甚至可以选择带有 GPU 的 CUDA/OpenCL 以获得额外的吞吐量,而这种与其他答案相反的解决方案看起来非常令人尴尬地可并行化,因为 1 个输入独立于其他输入进行计算。

答案 9 :(得分:-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;

}