【问题标题】:In C How to use leftmost digit from an integer在C中如何使用整数中最左边的数字
【发布时间】:2014-03-27 22:35:38
【问题描述】:

我想知道如何反转我的输出以匹配输入的数字。 例如,如果用户输入543210,我希望输出为:Five Four Three Two One Zero。但相反,它被反转了,我不知道如何反转它。

我不能使用循环或其他任何东西。

代码:

int main(void){
        int value;
        int digit;

        printf("enter:");
        scanf("%i", &value);

        while(value)
        {


                digit = value % 10;
                value = value / 10;

                if(digit != 0)
                {

                        switch(digit)
                        {
                                case 0:
                                        printf("zero ");
                                        break;
                                case 1:
                                        printf("one ");
                                        break;
                                case 2:
                                        printf("two ");
                                        break;
                                case 3:
                                        printf("three ");
                                        break;
                                case 4:
                                        printf("four ");
                                        break;
                                case 5:
                                        printf("five ");
                                        break;
                                case 6:
                                        printf("six ");
                                        break;
                                case 7:
                                        printf("seven ");
                                        break;
                                case 8:
                                        printf("eight ");
                                        break;

                                case 9:
                                        printf("nine ");
                                        break;
                        }
                }

        }

        return 0;

}

示例:如果用户输入 1234
输出将是:四三二一。

我将如何解决它:一二三四。

【问题讨论】:

  • 您熟悉递归这个概念,还是有兴趣看到新事物?
  • 将它们转换为字符串似乎是解决这个问题的最自然方法。
  • 将数据存储到字符串数组中,而不是直接打印出来。一旦你完成反向打印它们,你就有了。这是我想到的第一件事,但我敢打赌,这个问题有更好的解决方案。
  • 那么递归确实是您的解决方案。但是您已经使用了一段时间(只是说)
  • 注意:您测试 if digit != 0 并且在 if 语句中,您在 digit 上执行一个值为 0 的 switch case。这是浪费空间,因为它保证不会发生。去掉 if 语句,这样输入 0 仍然可以打印值。

标签: c


【解决方案1】:

既然您已经说过不允许使用循环,那么递归确实是您可能希望使用的东西。我个人不确定不将递归视为循环是否正确,但无论如何。

您在那里使用while,这也是一个循环。如果您允许使用循环,那么您只需在您的代码中进行以下易于理解的修改,并获得您想要的输出:

    ...
    int input;  // <-- added this
    int value;
    int digit;

    printf( "enter:" );
    scanf( "%i", &input );  // <-- notice the change in variable usage

    value = 0;
    while ( input ) {
        value = 10 * value + input % 10;    // adds the last digit of input to value from right
        input /= 10;
    }

    while ( value ) { ... }
    ...

如果您不允许使用循环,那么您可能需要使用一个特殊的函数,一个为单个案例输出特定值并在任何其他案例中返回自身的函数。你需要一个递归函数。检查这个简单的例子:

// This is in maths, not C
f(x) = 2x + 1   for all integer x >= 0

在多种方式中,这是一种描述函数的方式,它将0 映射到1,然后将1 映射到3,然后将n 映射到2n + 1。如果我们想定义完全相同的函数recursively

// In maths
f(x = 0) = 1    for x = 0
f(x > 0) = f(x-1) + 2   for integer x > 0

你看到里面发生了什么吗?意思是每个后续f(x) 比前一个f(x-1) 大2。但更重要的是,该函数正在调用自己!如果仔细观察,被调用的函数f(x-1) 也会调用自身:

f(x) = f(x-1)         + 2
f(x) = f(x-2) + 2     + 2
f(x) = f(x-3) + 2 + 2 + 2
...
// all these are the same

所有这些越来越深的呼唤都必须在某个地方结束,而那个地方就是f(x-...)f(0),它已被明确定义为1

这就是递归的全部意义所在。让我把我上面给出的例子用 C 写出来:

// non-recursive version
int fnonrec( int x ){
    return 2 * x + 1;
}

// recursive version
int frec( int x ){
    if ( x == 0 )
        return 1;   // explicit return value for f(0)
    else    // redundant else, hehe
        return frec( x - 1 ) + 2;
}

函数的定义看起来与数学中的定义非常相似,不是吗?是的,好吧,我不认为给你问题的答案会对我很好。我只能说,你可以用递归函数很好地反向打印东西。

【讨论】:

  • 有趣 - 我试过了,但仍然不能让它正常工作。我试图使它与 switch 语句一起工作,但是它可以工作,而不是当用户输入时:“12345”-我只得到最正确的数字(5)-而不是“一二三(等..) )。
  • @user3470588 它正在我这边工作......当我输入123时,我得到输出one two three
  • @CeFu 你确定你写的value = 10 * value + input % 10; 行是正确的,还是你没有不小心写了input /= 100000; 之类的?这是它确实有效的证据:ideone.com/MGNGzq
  • 我打破了我的 while 循环,它持有 "digit = value % 10";这导致了我的错误。谢谢你的帮助!我可以投票哈哈。
  • @CeFu 不客气,兄弟,我希望我也能提供一些关于递归函数的额外信息。
【解决方案2】:

//将用户输入存储到int变量“value

char str[15];

sprintf(str, "%d", value);

然后您可以使用strrev 函数来反转字符串数组。从那里操纵它。

【讨论】:

    【解决方案3】:
    #include <stdio.h>
    
    void print(int v){
        static char *numbers[] = {
            "zero","one","two","three","four",
            "five","six","seven","eight","nine"
        };
        int digit = v % 10;
        int value = v / 10;
        if(value){
            print(value);
            printf(" %s", numbers[digit]);
        } else 
            printf("%s", numbers[digit]);
    }
    
    int main(void){
        int value;
    
        printf("enter:");
        scanf("%i", &value);
        print(value);
    
        return 0;
    }
    

    【讨论】:

    • +1 这是最好的解决方案。 (可以为学习者使用一些解释。)
    【解决方案4】:

    使用递归函数和参数中的数字的示例:

    #include <stdio.h>
    
    void    display(char c)
     {
      char *numbers[] = {
      "zero","one","two","three","four",
      "five","six","seven","eight","nine "
     };
     printf("%s ", numbers[c]);
    }
    
    int     aff_num(char *c)
    {
      if (*c == '\0')
        return (0);
      display(*c-48);
      aff_num(++c);
      return (1);
    }
    
    int     main(int argc, char **argv)
    {
     if (argc < 2)
      {
        printf("Need numbers\n");
        return (-1);
      }
     aff_num(argv[1]);
     return (0);
    }
    

    【讨论】:

    • *c- '0' 优于 *c-48
    【解决方案5】:

    我是一名 python 黑客,我几乎从不使用 C 编程。也就是说:

    #include <stdlib.h>
    #include <stdio.h>
    
    int highest_power_of_ten(int value){
        int exponent = 0;
        int tens = 1;
        while(value > tens){
            tens *= 10;
            exponent += 1;
        }
        return exponent-1;
    }
    int pow(int base, int exponent){
        if (exponent == 0)
            return 1;
        int temp = base;
        while(exponent > 1){
            base *= temp;
            exponent -= 1;
            }
        return base;
    }
    int main(int argc, char** argv){
        char* digits[] = 
        {"zero","one","two","three","four","five","six","seven","eight","nine"};
        int value, n, exp, x;
        scanf("%i", &value);
    
        while(highest_power_of_ten(value)>0){
            exp = highest_power_of_ten(value);
            x = pow(10, exp);
            n = value/x;
            printf("%s ",digits[n]);
            value -= n*x;
        }
        printf("%s\n", digits[value]);
        //system("PAUSE"); for windows i guess
        return 0;
    }
    

    【讨论】:

      【解决方案6】:

      另一种按正确顺序获取数字的方法:

      例如要获得 123 中第一个位置的数字,将 123 除以 100,得到第二个 - 123 / 10,得到第三个 123 / 1。这等于:值 / 10 ^(所需数字的索引) 所以我们要做的是

      1. 通过计算 log10(value) 得到(剩余)数字的长度。
      2. 然后通过将值除以 10^length(长度为 1)来获得(剩余的)第一个(最高有效位)数字。
      3. 计算 value := value - 10^length 并从 1 开始,除非结果为 0(注意以 0 结尾的数字)。

        while (value)
        {
            len    = log10(value);
            digit  = (int) value / pow(10, len);
            value -= pow(10, len);
        }
        

      而且您的代码永远不会输入 case 0。要解决这个问题,只需留下 if(digit != 0) - 这就是我写“注意 0”时的意思。

      if(digit != 0)          // enters if digit is not 0
      {
          switch(digit)
          {
              case 0:         // enters if digit is 0
               ...   
          }
      }
      

      【讨论】:

      • 对您的答案进行更详细的解释会很有帮助。较新的开发人员不一定能理解您试图传达的概念。
      • 我编辑了我的帖子。我希望现在能更清楚地理解。
      猜你喜欢
      • 1970-01-01
      • 2011-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-25
      • 1970-01-01
      • 2018-05-23
      • 2021-11-21
      相关资源
      最近更新 更多