【问题标题】:Reversing last n digits of an Integer in C在C中反转整数的最后n位
【发布时间】:2020-12-17 13:13:18
【问题描述】:

我需要编写一个需要 2 位数字(X 和 n)的程序,然后打印 X,并将 X 的最后 n 位反转。

例如

输入:12345 3

输出:12543

输入:523 2

输出:532

我已经写了一个控制机制来检查n是否大于或等于X的位数 例如,如果输入是 6343 和 7,则程序会打印出应该更改输入并再次接受输入。

我的主要问题是我找不到反转最后 n 位数字的算法。我可以用这段代码反转任何 int

  int X, r = 0;

  printf("Enter a number to reverse\n");
  scanf("%d", &n);

  while (X != 0)
  {
    r = r * 10;
    r = r + n%10;
    X = X/10;
  }

  printf("Reverse of the number = %d", r);

但我不知道两个如何反转最后一个数字。你能给我一些想法吗?

【问题讨论】:

  • 可能最容易将输入值转换为 char 数组,修改它,然后转换回来(如果需要)。
  • 另外你的'n'变量是未声明的。除非这只是您代码的一部分?
  • 或者,由于您的输入是一个字符串,所以首先不要费心将其转换为 int。 (例如,不要使用scanf("%d",...
  • 注意使用pow(10,...) 及其几乎正确答案的解决方案的浮点问题。最好将整数数学用于整数类型问题。

标签: c


【解决方案1】:

我不知道如何只反转最后一个数字

使用pow(10,n) 分隔数字 - 请参阅后面的代码。

unsigned reverse_last_digits(unsigned x, unsigned n) {
  unsigned pow10 = powu(10, n);
  unsigned lower = x%pow10;
  unsigned upper = x - lower;
  return upper + reverseu(lower, n);
}

创建一个循环来提取最低有效数字 (%10) 并通过应用该数字构建另一个整数。(y = y*10 + new_digit)

unsigned reverseu(unsigned x, unsigned n) {
  unsigned y = 0;
  while (n-- > 0) {
    y = y*10 + x%10;
    x /= 10;
  }
  return y;
}

对于整数类型问题,请考虑整数辅助函数并避免使用像 pow() 这样的浮点函数,因为它们可能只提供近似结果。很容易编码一个整数pow()

unsigned powu(unsigned x, unsigned expo) {
  unsigned y = 1;
  while (expo > 0) {
    if (expo & 1) {
      y = x * y;
    }
    expo >>= 1;
    x *= x;
  }
  return y;
}

测试

int main() {
  printf("%u\n", reverse_last_digits(12345, 3));
  printf("%u\n", reverse_last_digits(523, 2));
  printf("%u\n", reverse_last_digits(42001, 3));
  printf("%u\n", reverse_last_digits(1, 2));
}

输出

12543
532
42100
10

代码使用unsigned 而不是int 来避免int 上的未定义行为 (UB) 溢出。

【讨论】:

  • reverse_last_digits(42001, 3) 返回错误值 42001 而不是 42100,因为 reverseu(1) 返回 1。
【解决方案2】:
It is an easy one.
1. let say the number you want to reverse is curr_number;
2. Now, the places you want to reverse is x; 
 (remember to verify that x must be less than the number of digit of curr_number);
3. now, just take a temp integer and store curr_number / pow(10,x) ('/' = divide and pow(10,x) is 10 to the power x)
4. now, take a second number temp2, which will store curr_number-(temp * pow(10,x) )
5. reverse this temp2 (using your function)
6. now, answer = (temp * pow(10,x) ) + (temp2) //(note temp2 is reversed)

步骤示例:

  1. curr_number = 1234567
  2. 您要反转的地方是 3 个
  3. temp = 1234567 / (10^3)​​ 即 (1234567/1000) = 1234(因为它是 int 类型)
  4. temp2 = 1234567 - (1234*10^3)​​ 即 1234567 - 1234000 = 567
  5. 反向(567) = 765
  6. 答案 = (1234 * 10^3)​​ + 765 = 1234765

【讨论】:

    【解决方案3】:
    • 创建两个变量

      • lastn 存储最后 n 位 (345)
      • r 存储反转的最后 n 位 (543)
    • 从原始数字中减去lastn (12345 - 345 = 12000)

    • r添加到上述数字(12000 + 543 = 12543)

    int c = 0; // count number of digits
    int original = x;
    int lastn = 0;
    while (x != 0 && c < n) {
        r = r * 10;
        r = r + x % 10;
        lastn += (x % 10) * pow(10, c);
        x = x / 10;
        c++;
    }
    printf("reversed: %d\n", original - lastn + r);
    

    【讨论】:

    • 不赞成使用pow 完成此任务。另外你为什么停在x == 0garble(1, 2) 应该返回 10
    【解决方案4】:

    如果您在使用char 时没有问题,您可以这样做

    #include <stdio.h>
    #include <string.h>
    
    #define SIZE 10
    
    int main() {
    
        char n[SIZE]; // the Number;
        int x; // number of last digits of n to reverse
        int len; // number of digits of n
    
        scanf("%s%d", n, &x);
    
        len = strlen(n);
    
        for(int i = 0; i < len; i++) {
        
            i < len - x ? printf("%c", n[i]) : printf("%c", n[2*len -1 - i - x]);
        }
    
        return 0;
    }
    

    如果您愿意,可以通过将for 分成两部分来使程序更具可读性

    for(int i = 0; i < len - x; i++) {
        printf("%c", n[i]);
    }
    for(int i = len-1; i >= len - x; i--) {
        printf("%c", n[i]);
    }
    

    注意:如果 n > x(即如果你想交换比你得到的数字更多的数字),程序将无法运行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      • 2015-09-17
      • 1970-01-01
      • 2017-11-18
      相关资源
      最近更新 更多