C递归反转一个数字

时间:2018-01-12 13:00:15

标签: c algorithm recursion

我有一个分配来创建一个收到一个数字的函数,然后返回相反的数字。

E.G:

Input : 12343 
Output : 34321

不允许循环,输入只是数字。

这是我尝试过的:

long GetReverse(unsigned long n)
{
    if (n < 10)
        return n % 10;
    else
        return  10 * GetReverse(n / 10) + n % 10;
}

虽然这回复了我相同的输入而没有反转数字(我知道这里的问题是什么,我只是想不出办法)

有什么想法吗?

编辑:这是我提出的解决方案:

int numOfMulti(unsigned long num) {
    if (num < 10)
        return 1;
    return 10 * numOfMulti(num / 10); 
}

long GetReverse(unsigned long n)
{
    if (n < 10)
        return n % 10; 
    else
        return  n % 10 * numOfMulti(n) + GetReverse(n / 10) ; 
}

无法找到没有辅助功能或静态变量的解决方案。

14 个答案:

答案 0 :(得分:3)

这很容易。请尝试我的解决方案。没有LOOPS,一个参数。

long GetReverse(unsigned long n)
{
    static unsigned long m = 0;
    static int recursive_level = 0;
    recursive_level++;
    if (n < 10) {
        recursive_level--;
        m = m * 10 + n;
        int temp = m;
        if (recursive_level == 0) {
            m = 0;
        }
        return temp;
    }
    m = m * 10 + (n % 10);
    GetReverse(n / 10);
    recursive_level--;
    int temp = m;
    if (recursive_level == 0) {
        m = 0;
    }
    return temp;   
 }

答案 1 :(得分:2)

您需要将2个元素传递给GetReverse函数,因为最后一个数字必须在左侧移位:

long GetReverse(unsigned long n, unsigned long m)
{
    if (n < 10)
        return 10 * m + n;
    else
        return  GetReverse(n / 10, 10 * m + n % 10);
}

然后,您可以致电GetReverse(12343, 0)并按预期获得34321

答案 2 :(得分:2)

这很愚蠢,不应该在现实生活中使用,但符合要求:

unsigned long GetReverse(unsigned long n)
{
    if (n < 10)
        return n;
    else
        return n % 10 * lround(pow(10,floor(log10(n)))) + GetReverse(n / 10);
}

答案 3 :(得分:1)

这里的解决方案只接受一个参数,尽管您只能使用最低32位作为输入:

uint64_t rev(uint64_t n)
{
    uint32_t _n = n;
    uint32_t _m = n >> 32;
    return _n < 10 
        ? 10 * _m + _n
        : rev(_n / 10 + (uint64_t)(10 * _m + _n % 10) * 65536 * 65536)
    ;
}

int main(){
    uint32_t n = 12345;
    n = rev(n);
}

本质上系数存储在n的高阶位中。在许多方面,这是一个可怕的设计,因为我所做的只是使用单个参数,其中应该有两个参数,并且我依赖于(明确定义的)缩小调用站点的无符号转换!但它确实显示了使用固定宽度无符号类型的优雅。

答案 4 :(得分:1)

这个怎么样?

#include <stdio.h>
#include <math.h>

long GetReverse(unsigned long n){
    if (n < 10){
        return n;

    } else {
        unsigned long r = GetReverse(n / 10);          
        int p = snprintf(NULL, 0, "%lu", r);    
        return lround(pow(10, p)) * (n % 10) + r; 
    }
}

int main(void){
    unsigned long n = 112233445566778899;   
    printf("%lu", GetReverse(n));   
    return 0;
}

答案 5 :(得分:0)

要将最后一位数字放在首位,您需要将该位数乘以10,对于数字中的每个数字:

#include <math.h>

long GetReverse(unsigned long n)
{
    if (n < 10)
        return n;  // Removed the % 10 as it is not needed when n is < 10
    else {
        long digit = n%10;
        long factor = (long) pow(10, (int)log(n));
        return  digit * factor + GetReverse(n / 10);
    }
}
使用

logpow代替循环来计算n中的位数。请注意this may fail,除非pow的实施足够好。我使用gcc(GCC)4.8.5 20150623(Red Hat 4.8.5-16)进行了测试,对于适合long的结果,该组合为整数幂10产生了正确的结果。

答案 6 :(得分:0)

没有循环,没有变量,没有其他参数!

#include <stdio.h>
unsigned long reverse(unsigned long num)
{
if (num < 10) return num;
if (num < 100) return 10 * (num %10) + reverse(num/10);
if (num < 1000) return 100 * (num %10) + reverse(num/10);
if (num < 10000) return 1000 * (num %10) + reverse(num/10);
if (num < 100000) return 10000 * (num %10) + reverse(num/10);
if (num < 1000000) return 100000 * (num %10) + reverse(num/10);
if (num < 10000000) return 1000000 * (num %10) + reverse(num/10);
if (num < 100000000) return 10000000 * (num %10) + reverse(num/10);
return 100000000 * (num %10) + reverse(num/10);
}

int main(int argc, char **argv)
{
unsigned long num, rev;

if (argc < 2) return 1;
sscanf(argv[1], "%lu", &num);

rev = reverse(num);
printf("%lu -->> %lu\n", num, rev );

return 0;
}

或者,使用辅助函数(变量)

[注意:这具有二次复杂度(关于位数)]

unsigned long tencount(unsigned long num)
{
if (num < 10) return 1;
return 10 * tencount( num/10);
}

unsigned long reverse2(unsigned long num)
{
if (num < 10) return num;
return tencount(num) * (num %10) + reverse2(num/10);
}

答案 7 :(得分:0)

假设32位长,你可以在没有循环或递归的情况下完成;

long GetReverse(unsigned long n)
{
    unsigned long x = ((n/1000000000) +
                      ((n/100000000)%10)*10 +
                      ((n/10000000)%10)*100 +
                      ((n/1000000)%10)*1000 +
                      ((n/100000)%10)*10000 +
                      ((n/10000)%10)*100000 +
                      ((n/1000)%10)*1000000 +
                      ((n/100)%10)*10000000 +
                      ((n/10)%10)*100000000 +
                      ((n)%10)*1000000000);

    return (x/(9*(x%10==0)+1)/
            (9*(x%100==0)+1)/
            (9*(x%1000==0)+1)/
            (9*(x%10000==0)+1)/
            (9*(x%100000==0)+1)/
            (9*(x%1000000==0)+1)/
            (9*(x%10000000==0)+1)/
            (9*(x%100000000==0)+1)/
            (9*(x%1000000000==0)+1));
}

答案 8 :(得分:0)

这是一个解决方案:

int reverse(int i) {
    static int p = 0;
    if (i==0) { int r = p; p = 0; return r; }
    p = 10*p+i%10;
    return reverse(i/10);
}

想法是使用第二个参数,但由于它仅用于存储部分结果,因此可以使用静态变量。为了能够重用该函数,您只需要在递归结束时重置静态。

因为这样的函数不是内卷,意味着reverse(reverse(x))不等于x,所以请考虑x=1000。如果要进行对合,则需要在表示值的C字符串上定义它。

答案 9 :(得分:0)

C递归反转一个数字

  

我有一个分配来创建一个接收数字并返回反转数字的函数   不允许循环,输入只是数字。

添加辅助递归函数。 @Art
没有静态变量,不需要浮点数学。

以下符合目标:
1)使用的递归 2)函数接收一个数字并返回反转的数字
3)不允许循环,输入只是数字

#include <stdio.h>
#include <stdlib.h>

static unsigned reverse_helper(unsigned x, unsigned *pow10) {
  if (x < 10) {
    *pow10 = 10;
    return x;
  }
  unsigned y = reverse_helper(x / 10, pow10);
  y += *pow10 * (x%10);
  *pow10 *= 10;
  return y;
}

unsigned reverse(unsigned x) {
  unsigned pow10 = 1;
  unsigned y = reverse_helper(x, &pow10);
  printf("%10u %10u\n", x, y);
  return y;
}

int main(void) {
  reverse(0);
  reverse(9);
  reverse(10);
  reverse(99);
  reverse(100);
  reverse(1234);
  reverse(123456789);
}

输出

         0          0
         1          1
         9          9
        10          1
        99         99
       100          1
      1234       4321
 123456789  987654321

答案 10 :(得分:0)

像OP这样的解决方案还使用了2个递归函数。

使用1个参数递归函数,没有浮点数,没有静态变量。

class Time(val hours: Int, val minutes: Int, val seconds: Int) {
    fun serialize(): String {
        return "%02d:%02d:%02d".format(hours, minutes, seconds)
    }
}

答案 11 :(得分:0)

如何调用像char* getReverse(int n)之类的函数那么你可以使用mod和concatenation来获得反向。然后在调用方法int getReverse(int n)中将字符串解析为int。您可以使用递归然后单行来进行解析。不需要循环和一个参数。

答案 12 :(得分:0)

这是我完全可重入的版本,没有额外的变量。它通过使用ldiv( num / 10 )获得商和余数,然后返回余数乘以10 ^(商数中的数字)加到商的反向(代码被格式化以删除滚动条 - 通常我&#39 ; d有空白行和更多大括号):

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
/* unsigned long power function */
unsigned long lpow( unsigned long base, unsigned long exp )
{
    unsigned long result = 1UL;
    while ( exp )
    {
        if ( exp & 1 )
            result *= base;
        exp >>= 1;
        base *= base;
    }
    return( result );
}

/* count the number of decimal digits */    
unsigned long numdigits( unsigned long num )
{
    return( floor( log10( num ) ) + 1 );
}

unsigned long reverse( unsigned long in )
{
    ldiv_t tmp = ldiv( in, 10UL );
    if ( tmp.quot == 0 )
        return( tmp.rem );
    return( reverse( tmp.quot ) + tmp.rem * lpow( 10, numdigits( tmp.quot ) ) );
}
来自https://stackoverflow.com/a/101613/4756299

unsigned long lpow()函数 来自https://stackoverflow.com/a/1068870/4756299

unsigned long numdigits()函数

这样称呼:

int main( int argc, char **argv )
{
    for ( int ii = 1; ii < argc; ii++ )
    {
        unsigned long num = strtoul( argv[ ii ], NULL, 10 );

        printf( "Reverse of %lu is %lu\n", num, reverse( num ) );
    }

    return( 0 );
}

答案 13 :(得分:0)

对于初学者,不清楚为什么返回类型被声明为long,而参数的类型为unsigned long

long GetReverse(unsigned long n);
^^^^            ^^^^^^^^^^^^^

要拥有更大的整数,最好声明参数和返回类型,如unsigned long long int

可以使用本地静态变量定义函数,该变量将保持计算的反转值。

在这里。

unsigned long long int GetReverse(unsigned long long int n)
{
    const unsigned long long int Base = 10;
    static unsigned long long int reversed;

    unsigned long long int tmp;

    reversed = Base * reversed + n % Base;

    return (n /= Base ) == 0 ? tmp = reversed, reversed = n, n = tmp, n
                             : GetReverse(n);
}

在下面的示范程序中,显示了该功能的工作原理。

#include <stdio.h>

unsigned long long int GetReverse(unsigned long long int n)
{
    const unsigned long long int Base = 10;
    static unsigned long long int reversed;

    unsigned long long int tmp;

    reversed = Base * reversed + n % Base;

    return (n /= Base ) == 0 ? tmp = reversed, reversed = n, n = tmp, n
                             : GetReverse(n);
}

int main(void) 
{
    const unsigned long long int Base = 10;

    for ( unsigned long long int i = 1, n = 0; i < Base; i++ )
    {
        n = Base * n + i;

        printf( "%llu\n", n );
        printf( "%llu\n", GetReverse( n ) );
        putchar( '\n' );
    }

    return 0;
}

程序输出

1
1

12
21

123
321

1234
4321

12345
54321

123456
654321

1234567
7654321

12345678
87654321

123456789
987654321