以相反顺序打印数字的数字,不带数组或函数

时间:2009-12-24 10:02:07

标签: c string integer

作为一个家庭作业问题,我正在从stdin读取十进制int,将其转换为另一个基础(也是从stdin提供)并将其打印到屏幕上。

这是我到目前为止所得到的:

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

int main()
{
    int num, base, remainder, quotient;
    printf("please enter a positive number to convert: ");
    scanf("%d", &num);
    printf("please enter the base to convert to: ");
    scanf("%d", &base);

    remainder = quotient = 1;

    // validate input
    if (num < 0 || base < 0) {
        printf("Error - all numbers must be positive integers!\n");
        return 1;
    }

    // keep dividing to find remainders
    while (quotient > 0) {
        remainder = num % base;
        quotient = num / base;
        num = quotient;
        if (remainder >= 10) {
            printf("%c", remainder + 55);
        } else {
            printf("%d", remainder);
        }
    }   
    printf("\n");
    return 0;
}   

这很有效,只是它使用的算法计算从最低有效数字到最高有效数字的转换数字,从而反向打印。因此,例如,将 1020 转换为十六进制( 0x3FC )将打印 CF3

是否有一个技巧可以用来反转这些数字以正确的顺序打印。我只能使用if-else,而简单的数学运算符和printf()/ getchar()/ scanf() - 没有函数,数组或指针。感谢。

10 个答案:

答案 0 :(得分:3)

(删除了帖子的原始部分,因为它不是解决方案)

然后我能看到的唯一解决方案是执行你现在拥有数字的次数的循环。

首先,你计算所有数字直到你到达最后,然后打印出来。

然后你取原始值+基数并再次开始分割,直到你达到第二个“最高值”数字。打印出来。

这是一个双循环,你计算两次,但你不使用额外的存储空间。

答案 1 :(得分:3)

这是一个很好的尝试,也是一个很好的措辞问题。如果我们有更多的人以这种明确的方式提问:

这些限制似乎是人为的。我想你还没有在类中学过函数,数组,指针等,但我认为这个问题并不是没有函数和/或数组就可以优雅地解决。

无论如何,你可以这样做:

curr := base
pow := 1
while num / curr >= 1 do:
    curr := curr * base
    pow := pow + 1

while pow >= 1:
    pow := pow - 1
    print floor(num / base ** pow)
    num := mod(num, base ** pow)

基本上,您要计算第一个循环中需要多少位数,然后再按正确的顺序打印数字。

您的代码的一些特定问题。我理解这是C课程的开始,但是现在知道这些问题比从未意识到这些问题更好:

printf("please enter a positive number to convert: ");

在此之后您应该添加fflush(stdout)以确保在调用scanf()之前显示输出。默认情况下,stdout在许多系统上都是行缓冲的,因此在程序等待输入之前可能不会出现提示。

printf("please enter the base to convert to: ");

与上述相同。

    if (remainder >= 10) {
        printf("%c", remainder + 55);
    } else {
        printf("%d", remainder);
    }

你假设是ASCII字符集。这不一定是真的。但是没有数组或指针,就没有简单的方法来打印与10...对应的字母表。此外,您的代码可能会为base > 36打印奇怪的字符。

您还应该意识到安全使用scanf()非常困难。希望您以后能够学到更好的获取方式。

答案 2 :(得分:1)

在一个循环中,您可以计算位数和big_base 在第二个循环中,您可以输出从最重要的数字开始的数字,如下所示:

n = 1020,3个十六进制数字,big_base = 16 * 16

1st step
1020 /(16 * 16)= 3

2nd step
n = 1020-3 *(16 * 16)= 252
252 /(16)= 15, F

3rd step
n = 252 - 15 * 16 = 12, C

答案 3 :(得分:1)

嘿!我认识到我在学校的第一年也有一份着名的家庭作业(@Epitech学生:不要复制/粘贴以下代码,尝试提出自己的解决方案,这是为了你自己的利益^^)

问题的解决方案是以递归方式执行问题:

void    my_putnbr_base(int num, int base)
{
  int   start;
  int   remainder;

  remainder = num % base;
  start = (num - remainder) / base;
  if (start != 0)
    my_putnbr_base(start, base);
  if (remainder >= 10)
    printf("%c", remainder + 55);
  else
    printf("%d", remainder);
}

你的作业是否指定它只适用于正数?如果没有,则很容易包含负数处理:

void    my_putnbr_base(int num, int base)
{
  int   start;
  int   remainder;

  if (num < 0)
    {
      putchar('-');
      my_putnbr_base(-num, base);
    }
  else
    {
      remainder = num % base;
      start = (num - remainder) / base;
      if (start != 0)
        my_putnbr_base(start, base);
      if (remainder >= 10)
        printf("%c", remainder + 55);
      else
        printf("%d", remainder);
    }
}

@arno:这是真的,因为例程是使用ASCII表。如果我们想要一些灵活的东西,我们需要参数的基础。例如:

>> my_putnbr_base(4242, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
39U
>> my_putnbr_base(42, "0123456789ABCDEF")
2A

这实现了示例:

void    my_putnbr_base(int num, char *base)
{
  int   start;
  int   remainder;
  int   len;

  len = strlen(base);
  if (num < 0)
    {
      putchar('-');
      my_putnbr_base(-num, base);
    }
  else
    {
      remainder = num % len;
      start = (num - remainder) / len;
      if (start != 0)
        my_putnbr_base(start, base);
      printf("%c", base[remainder]);
    }
}

我希望它能解决你的问题!

编辑:我没有正确阅读^^你不允许使用函数,所以递归是不可能的......这是一种交互方式,你可以把它放在一个main()中。您可以通过添加负数处理和灵活的基础来改进此代码,如我所示:)

int     my_putnbr_base_it(int num, int base)
{
  unsigned int  quotient = 1;
  unsigned int  remainder;

  while ((num / quotient) >= base)
    quotient *= base;
  while (quotient)
    {
      if ((remainder = (num / quotient) % base) < 10)
        printf("%d", remainder);
      else
        printf("%c", 55 + remainder);
      quotient /= base;
    }
  return (0);
}

希望它现在能解决所有问题!

答案 4 :(得分:0)

您可以重写计算每个数字的代码片段以充当状态机。它将以初始状态开始并计算位数,然后将状态更改为“打印第N位”以打印最高位数,然后更改状态以进入较低位数等,直到它进入最终州。在循环中运行它将以正确的顺序输出所有数字。

答案 5 :(得分:0)

你可以使用两个循环。第一个保持产生基数的功率,直到它找到大于输入数的功率。第二个从这里开始(或者更确切地说,之前是一个幂)并且返回到基数^ 0(即1)以首先计算最重要的输出数字。

未经测试的伪代码:

// Determine highest power, don't actually need "power" it's just there for illustration
power = 0;
baseraisedtopower = 1;
while (baseraisedtopower <= input)
{
    baseraisedtopower *= base;
    power++;
}
// Go back one step, could have saved previous result
baseraisedtopower /= base;
power--;
// Output
while (input > 0)
{
    // Integer division, truncate
    quotient = input / baseraisedtopower;
    printf("%c", quotient + 55);
    input -= quotient * baseraisedtopower;
    baseraisedtopower /= base;
    power--;
}

答案 6 :(得分:0)

您可以试试这种方法。 这更像是一个概念证明,你仍然需要处理一些特殊情况,但是,嘿,那是你的功课:)

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

int main()
{
    int num, base, remainder, quotient;
    int divider;

    printf("please enter a positive number to convert: ");
    scanf("%d", &num);
    printf("please enter the base to convert to: ");
    scanf("%d", &base);

    remainder = quotient = 1;

    // validate input
    if (num < 0 || base < 0) {
        printf("Error - all numbers must be positive integers!\n");
        return 1;
    }

    // First get the highest divider
    divider = base;

    while ( num / divider > base ) {
      divider *= base;
    }

    do {

      // Get the highest digit
      remainder = num / divider;

      // And update num accordingly
      num -= remainder * divider;
      divider /= base;

      if (remainder >= 10) {
        printf("%c", remainder + 55);
      } else {
        printf("%d", remainder);
      }

    } while ( divider );

    printf("\n");
    return 0;
}

答案 7 :(得分:0)

有趣的任务,你有作为一个功课。 我是初学者程序员,我试图解决这个问题。

以下代码正在运行(我没有经过多少测试,显然正在运行)。我相信这不是最佳和最佳的解决方案,但这是我唯一能想到的。它应该适用于任何基础。不幸的是,它不会转换10-> A,11-> B等:

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

int main(){
        int nr,base,res,tp,tpb,tpbt,r,rnr,lp,lpt,i;
        float baset,rt;

        /** Read number */
        printf("nr=");
        scanf("%d",&nr);

        /** Read base */
        printf("base=");
        scanf("%d",&base);

        /** Returning result */
        res=0;

        /** Test if number is positive
        and base is bigger than 2 */
        if(nr<0||base<2){
                /** Error */
                res=1;
        }
        else{
                /** Determine how many
                digits are necessary */
                lp=0;
                baset=base;
                while(baset>1){
                        lp++;
                        baset/=10;
                }

                /** Determine full power
                of 10 when r has length of lp */
                tpb=1;
                while((lp--)>0){
                        tpb*=10;
                }

                /** Power of ten that will be
                incremented */
                tp=0;

                /** Converted number (will be printed
                as the result) */
                rnr=0;

                /** Algorithm */
                while(nr>0){
                        r=nr%base;
                        nr/=base;
                        rt=r;

                        /** Temporary lp for
                        r */
                        lpt=0;
                        while(rt>1){
                                lpt++;
                                rt/=10;
                        }

                        /** Temporary tpb for
                        lpt */
                        tpbt=tpb;
                        for(i=0;i<lpt;i++){
                                tpbt/=10;
                        }

                        /** Build number */
                        rnr+=r*pow((double)(tpbt),(double)(tp++));
                }
        }

        /** Show number */
        printf("number is: %d \n",rnr);

        return (res);
}

答案 8 :(得分:0)

根据建议,解决这个问题的方法是保持打印最后一个数字,并为每个数字重复循环。我通过保存先前的商和我每次到达时打印(然后重新设置数字并重新开始)来跟踪打印条件,然后将其重置为之前的那个。听起来很复杂,但对代码的更改很简单。循环的停止条件是当我连续2次打印时,因为大部分时间它只计算商/余数并且不打印任何内容,当连续打印2位数时,它就是最后两位。无论如何,这是代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int num, saved, base, remainder;
    int quotient, prev_q, stop_q, just_printed;

    printf("please enter a positive number to convert: ");
    scanf("%d", &num);
    printf("please enter the base to convert to: ");
    scanf("%d", &base);

    saved = num;
    remainder = quotient = prev_q = just_printed = 1;
    stop_q = 0;

    // validate input
    if (num <= 0 || base <= 0) {
        printf("Error - all numbers must be positive integers!\n");
        return 1;
    }

    // divide
    while (1) {
        remainder = num % base;
        quotient = num / base;
        num = quotient;

        // print if it's the last number and reset num to the next 
        if (quotient == stop_q) {
            if (remainder >= 10) { printf("%c", remainder + 55); } 
            else { printf("%d", remainder); }

            // if 2 consecutive printing occur, this means it's time to end this
            if (just_printed) { break; }

            // next time print when hitting the previous quotient
            stop_q = prev_q;

            // reset the number to the original value
            num = saved;


            just_printed = 1;
        } else {
            just_printed = 0;
        }
        prev_q = quotient;
    }   
    printf("\n");
    return 0;
}    

感谢所有投入的人!

答案 9 :(得分:0)

我们可以使用递归函数来反转数字的顺序:

我们需要这些库中的一些数学函数-stdlib.hmath.h

int reverse(int x)
{
    if(abs(x)<=9)
    {
        return x;
    }
    else
    {
        return reverse(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
    }
}

“ If语句”是递归函数的基本情况。

“ Else语句”乍看起来可能令人生畏,但实际上只是简单的算法。 floor(log10(abs(x))) 为我们提供了x的位数,因此((x%10)*(pow(10, (floor(log10(abs(x)))))))只是根据所需的反向数字将数字的“一个”位数放到正确的位置。

为了更好地理解,我们举一个例子,让 123 为我们需要反转的数字。函数reverse要做的第一件事是问自己 12 reverse(x/10))的相反方向,以及第二次使用参数 12调用该函数时,它会问自己与 1 相反的问题,这将是我们函数的基本情况。它将以abs(1)<=9的形式返回 1 ,现在将以((x%10)*(pow(10, (floor(log10(abs(x))))))开头 2 ,然后返回 21 3 将以相同的开头。

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

int reverse(int x);
int main()
{
    int x, revInt;
    scanf("%d", &x);           // input : 123
    revInt = reverse(x);
    printf("%d", revInt);      // output : 321
    return 0;
}