【问题标题】:format specifier and reversing a 32 bit signed integer格式说明符和反转 32 位有符号整数
【发布时间】:2020-06-03 21:39:54
【问题描述】:

我在一次采访中得到了一个代码来编写一个函数来反转一个 32 位有符号整数,我在第三次尝试中写了这个(适用于所有测试用例):

int fun(int x)
{
    char a[11]="";  //this will contain character form of absolute value of number 'x' 
    char b[11]="";  //this will contain reverse of absolute of number 'x'
    char e[11]="";

    short sign = -1;
    short index_a=0;
    short index_b=0;
    short index_e=0;
    short temp_index=0;

    if(x<0)
    {
        sprintf(a,"%u",(unsigned int)(-1*(long int)(x)));
        sprintf(e,"%u",(unsigned int)(-1*(long int)(pow(2,31)))); //setting the limits
        sign = -1;
    }
    else if(x>0)
    {
        sprintf(a,"%u",(unsigned int)x);
        sprintf(e,"%u",(unsigned int)(-1*(long int)(pow(2,31) - 1))); //setting the limits
        sign = 1;
    }
    else
      x=0;

    index_a = strlen(a);
    --index_a;

    //'b' will contain the reversed digits of array 'a'

    while(index_a>=0) //storing it in 'b' from a character by character in reverse order
    {
        b[index_b++] = a[index_a--];
    }

    //here index_a is equal to -1 and index_b is euqal to 'strlen(b)'


    if(index_b==10) //10 is the number of digits in (2^31 - 1) or (2^31)
    {
        while(temp_index<index_b)
        {
           if(b[temp_index]>e[index_e])
                return 0;
           else if(b[temp_index] < e[index_e])
                break;
           temp_index++;
           index_e++;
        }
    }

    return sign*atoi(b);
}

我被要求改进但我不能(后来知道这个问题是为了过滤 - 我猜我失败了) - 你能建议任何其他方法吗?

我遇到的主要问题是当变量x等于-(2^31)时,这就是为什么我不能简单地写x = abs(x)-您能否还建议我一些链接,我可以在其中深入了解有符号的无符号限制和格式说明符(%l 不适用于 sprintf,因此使用了 %u)。

约束 -

  • 如果发生上溢/下溢0将被返回。

  • 返回类型固定为int

  • 编号。参数是固定的。

【问题讨论】:

  • 如果我看到这样的pow(2,31)我知道我不应该雇用这个人。
  • 一个简单的请求就需要这么多代码。视为无符号,for 循环所有 sizeof(int) 位,用 & 和 | 抓取低位进入新的变种。以相反的方向移动输入和新变量直到完成。还有一些幻数异或可以用来更快地反转,或者使用内在的 rev 指令(如果存在)。
  • 您可以使用 INT32_MAX 和 INT32_MIN。您可以避免使用 3 个字符串缓冲区而只使用 1 个,您可以通过迭代到字符串的一半来反转字符串,将前面的字符替换为后面的字符。更重要的是,您可以添加文档和 cmets 来解释极端情况是什么。
  • @MichaelDorgan:问题不在于反转位。就是产生小数位取反表示的数字。
  • @EricPostpischil,将无符号值分配给有符号值充满了 perl。

标签: c


【解决方案1】:

如果要将其反转为十进制数:

三个版本

int reverse10(int val)
{
    long long result = 0 ;

    while(val)
    {
        result *= 10;
        result += val % 10;
        val /= 10;
    }
    if(result < INT_MIN || result > INT_MAX) return 0;
    return result;
}

int rev(int32_t val, int32_t *result)
{
    int32_t temp;
    int digit;
    *result = 0;

    while(val)
    {
        temp = *result;
        *result *= 10;
        if(temp != (*result / 10)) {*result = 0; return -1;}
        temp = *result;
        digit = val % 10;
        *result += digit;
        if(temp != (*result - digit)) {*result = 0; return -1;}
        val /= 10;
    }
    return 0;
}

int rev1(int val)
{
    int temp;
    int digit;
    int result = 0;

    while(val)
    {
        temp = result;
        result *= 10;
        if(temp != (result / 10)) return 0;
        temp = *result;
        digit = val % 10;
        result += digit;
        if(temp != (result - digit)) return 0;
        val /= 10;
    }
    return result;
}

【讨论】:

  • 从提供的代码中可以明显看出问题有处理溢出的要求,而这个答案并不满足。
  • @EricPostpischil 实际上没有。我问类似的问题,看看受访者是否理解问题。面试问题必须非常简单 - 但要表明人们通常压力很大,必须考虑到这一点
  • 返回类型是固定的 - int
  • 不过,mod div 10 也是我的方法。
  • @AgrudgeAmicus 我在这里没有发现任何问题 - 紫外线。如果代码必须返回int,则在函数末尾测试结果是否在范围 [INT_MIN...INT_MAX] 内,并根据需要处理超出范围的答案。
猜你喜欢
  • 2016-12-16
  • 2018-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-31
  • 2018-10-09
  • 2011-01-31
相关资源
最近更新 更多