从C中的长整数中提取个别数字

时间:2012-04-06 14:50:57

标签: c

我正在为C课程(第一门课程)做作业。 部分分配是编写代码,以便用户输入长达9位的数字,程序需要确定这个数字是“增加”/“真正增加”/“减少”/“真正减少”/“增加和减少“/”真正减少并且真正增加“/”不减少而不增加“。 (总共7个选项)

由于这是我们的第一项任务,除了课堂上教授的内容外,我们不允许使用任何其他内容:

do-while,for,while循环,else-if,if, 突破,继续 scanf,printf,modulo和基本运算符

(我们不能使用除stdio.h之外的任何库)

就是这样。我不能使用数组或getchar或任何这些东西。我可以用来接收用户输入的唯一功能是scanf

到目前为止,我已经用流程图和所有内容编写了算法,但我需要将用户的输入分成不同的数字。

例如,如果用户输入“1234 ...”,我想在a中保存1,在b中保存2,依此类推,然后在所有数字之间进行比较,以确定它们是否全部相等(增加和减少)或是否a> b> c ...(减少)等等。

我知道如何使用%和/运算符分隔每个数字,但我无法弄清楚如何将这些值“保存”在一个变量中,以后我可以用于比较。

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

printf("Enter a positive number : ");

do {
    scanf ("%ld", &number);
    if (number < 0) {
        printf ("invalid input...enter a positive integer: ");
        continue;
    }
    else break;
} while (1);

while (number < 0) {
    a = number % 10;
    number = number - a;
    number = number / 10;
    b = a;
}

7 个答案:

答案 0 :(得分:4)

为什么不将它们扫描为字符(字符串)?然后,您可以通过数组偏移量访问它们,方法是从ASCII字符代码中减去48的偏移量。您可以使用ctype.h中的isdigit验证字符是否为数字。


修改

由于你的教授采取了令人难以置信的心不在焉的限制:

#include <stdio.h>

int main()
{
  int number;
  printf("Enter a positive number: ");

  do
  {
    scanf ("%ld", &number);
    if (number < 0)
    {
      printf ("invalid input...enter a positive integer: ");
      continue;
    }
    else break;
  } while (1);

  int a = -1;
  int b = -1;
  int c = -1;
  int d = -1;
  int e = -1;
  int f = -1;
  int g = -1;
  int h = -1;
  int i = -1;

  while (number > 0)
  {
    if (a < 0) a = number % 10;
    else if (b < 0) b = number % 10;
    else if (c < 0) c = number % 10;
    else if (d < 0) d = number % 10;
    else if (e < 0) e = number % 10;
    else if (f < 0) f = number % 10;
    else if (g < 0) g = number % 10;
    else if (h < 0) h = number % 10;
    else if (i < 0) i = number % 10;

    number /= 10;
  }

  /* Printing for verification. */

  printf("%i", a);
  printf("%i", b);
  printf("%i", c);
  printf("%i", d);
  printf("%i", e);
  printf("%i", f);
  printf("%i", g);
  printf("%i", h);
  printf("%i", i);

  return 0;
}

最后的有效数字是正数,因此您可以根据不同的条件验证这些数字。

答案 1 :(得分:1)

我们假设你有这个号码23654

23654 % 10000 = 2 and 3654
3654 % 1000 = 3 and 654
654 % 100 = 6 and 54
54 % 10 = 5 and 4
4

这样你就可以获得所有数字。当然,你必须知道这个数字是否大于10000,1000,100或10,才能知道第一个除数。

使用sizeof来获取整数的大小,以避免使用巨大的if ... else语句

修改

让我们看看

if (number>0) {
    // Well, whe have the first and only digit
} else if (number>10) {
    int first_digit = number/10;
    int second_digit = number % 10;
} else if (number>100) {
    int first_digit = number/100;
    int second_digit = (number % 100)/10;
    int third_digit = (number % 100) % 10;
} ...

依此类推,我想

答案 2 :(得分:1)

要求你做没有阵列的循环是愚蠢的 - 但这是你老师的错,不是你的。

话虽这么说,我会做这样的事情:

char c;
while (1) {
    scanf("%c", &c);
    if (c == '\n')    /* encountered newline (end of input) */
        break;
    if (c < '0' || c > '9')
        break;        /* do something to handle bad characters? */
    c -= '0';
    /*
     * At this point you've got 0 <= c < 9. This is
     * where you do your homework :)
     */
}

这里的技巧是当你在程序中输入数字时,你会一次发送缓冲区,而不是一次发送一个字符。这意味着第一个scanf将阻塞,直到整个字符串(即“123823”或其他)与换行符('\ n')同时到达。然后这个循环在闲暇时解析那个字符串。

编辑为了测试数字的增加/减少,您可能认为需要存储整个字符串,但事实并非如此。只需定义一些其他变量即可记住重要信息,例如:

int largest_digit_ive_seen, smallest_digit_ive_seen, strict_increasing_thus_far;

等。等

答案 3 :(得分:1)

由于您只需要比较连续数字,因此在没有数组的情况下有一种优雅的方法:

int decreasing = 2;
int increasing = 2;

while(number > 9)
{
  int a = number % 10;
  int b = (number / 10) % 10;

  if(a == b)
  {
    decreasing = min(1, decreasing);
    increasing = min(1, increasing);
  }
  else if(a > b)
    decreasing = 0;
  else if(a < b)
    increasing = 0;

  number /= 10;
}

在这里,我们遍历数字(除以10)直到只剩下一个数字。我们在decreasingincreasing中存储了有关此时间点数的信息 - 2表示真正增加/减少,1表示增加/减少,以及{0 1}}表示不增加/减少。

在每一步,a都是数字,b是数字。然后,我们根据increasingdecreasing之间的比较更改ab

最后,应该很容易将increasingdecreasing的值转换为您想要的最终答案。

注意:函数min返回其2个参数中较小的一个。您应该能够编写自己的,或用if语句或条件替换这些行。

答案 4 :(得分:1)

// u_i is the user input, My homework asked me to extract a long long, however, this should also be effective for a long.

int digits = 0;
long long d_base = 1;
int d_arr[20];
while (u_i / d_base > 0)
{
    d_arr[digits] = (u_i - u_i / (d_base * 10) * (d_base * 10)) / d_base;
    u_i -= d_arr[digits] * d_base;
    d_base *= 10;
    digits++;
}

编辑:提取的单个数字现在位于int数组d_arr中。我不擅长C语言,所以我认为可以优化数组声明。

答案 5 :(得分:0)

以下是普通C中的一个工作示例:

#include <stdio.h>

unsigned long alePow (unsigned long int x, unsigned long int y);

int main( int argc, const char* argv[] )
{
   int enter_num, temp_num, sum = 0;
   int divisor, digit, count = 0;

    printf("Please enter number\n");
    scanf("%d", &enter_num);

   temp_num = enter_num;

   // Counting the number of digits in the entered integer
   while (temp_num != 0)
   {
       temp_num = temp_num/10;
       count++;
   }

   temp_num = enter_num;

   // Extracting the digits
   printf("Individual digits in the entered number are ");
   do
   {
       divisor = (int)(alePow(10.0, --count));
       digit = temp_num / divisor;
       temp_num = temp_num % divisor;

       printf(" %d",digit);
       sum = sum + digit;
   }
   while(count != 0);

   printf("\nSum of the digits is = %d\n",sum);

   return 0;
}


unsigned long alePow(unsigned long int x, unsigned long int y) {

    if (x==0) { return 0; } 
    if (y==0||x==1) { return 1; } 
    if (y==1) { return x; }
    return alePow(x*x, y/2) * ((y%2==0) ? 1 : x);
}

答案 6 :(得分:0)

我建议循环展开

int a=-1, b=-1, c=-1, d=-1, e=1, f=-1, g=-1, h=-1, i=-1; // for holding 9 digits
int count = 0; //for number of digits in the given number


if(number>0) {
i=number%10;
number/=10;
count++;
}

if(number>0) {
h=number%10;
number/=10;
count++;
}

if(number>0) {
g=number%10;
number/=10;
count++;
}
....
....
/* All the way down to the storing variable a */

现在,您知道位数(变量计数)并将它们存储在哪个变量中。现在你有了所有的数字,你可以用很多if来检查它们的“减少”,“增加”等等!

考虑到你的所有条件,我真的不能想到更好的解决方案。