8

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

由于这是我们的第一个作业,我们不允许使用除了课堂上教过的东西之外的任何东西:

do-while、for、while 循环、else-if、if、break、continue scanf、printf、模数和基本运算符

(我们不能使用除 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;
}
4

7 回答 7

5

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


编辑

由于您的教授设置了令人难以置信的心不在焉的限制:

#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;
}

最后的有效数字将为正数,因此这些是您验证以满足不同条件的数字。

于 2012-04-06T14:58:49.763 回答
2

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

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表示不增加/减少。

在每一步,a是个位,b是十位。然后,我们根据和之间的比较来更改increasing和。decreasingab

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

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

于 2012-04-06T15:48:54.087 回答
1

Let us suppose you have this number 23654

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

This way you can get all the digits. Of course, you have to know if the number is greater than 10000, 1000, 100 or 10, in order to know the first divisor.

Play with sizeof to get the size of the integer, in order to avoid a huge if...else statement

EDIT:

Let us see

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;
} ...

and so on, I suppose

于 2012-04-06T15:04:09.817 回答
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;

等等等等

于 2012-04-06T15:14:19.613 回答
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,所以我认为可以优化数组声明。

于 2018-12-11T14:25:02.503 回答
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);
}
于 2012-04-06T15:13:18.363 回答
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 来检查它们的“减少”、“增加”等!

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

于 2012-04-06T15:21:09.617 回答