簡體   English   中英

從 C 中提取單個數字

[英]Extracting individual digits from a long in C

我正在為 C(第一門編程課程)的課程做家庭作業。 作業的一部分是編寫代碼,讓用戶輸入一個長達 9 位的數字,程序需要確定這個數字是否在“增加”/“真正增加”/“減少”/“真正減少”/“增減”/“真減實增”/“不減不增”。 (共7個選項)

由於這是我們的第一個作業,因此我們不允許使用 class 中所教內容之外的任何內容:

do-while、for、while 循環、else-if、if、break、continue scanf、printf、模數和基本運算符

(除了 stdio.h,我們不能使用任何庫)

而已。 我不能使用 arrays 或getchar或任何類似的東西。 我唯一可以用來接收用戶輸入的 function 是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;
}

為什么不將它們掃描為字符(字符串)? 然后您可以通過數組偏移量訪問它們,方法是從 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;
}

最后的有效數字將是正數,因此這些是您驗證以滿足不同條件的數字。

由於您只需要比較連續的數字,因此有一種優雅的方法可以在不使用 arrays 的情況下執行此操作:

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是十位。 然后,我們根據ab之間的比較來改變increasingdecreasing

最后,應該很容易將increasingdecreasing的值變成你想要的最終答案。

注意:function min返回其 2 arguments 中較小的一個。您應該能夠編寫自己的代碼,或將這些行替換為if語句或條件語句。

讓我們假設你有這個數字 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 獲得 integer 的大小,以避免巨大的 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;
} ...

等等,我想

要求你在沒有 arrays 的情況下進行循環是愚蠢的——但那是你老師的錯,而不是你的錯。

話雖這么說,我會做這樣的事情:

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;

等等等等

// 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,所以我覺得數組聲明可以優化一下。

這是一個簡單的工作示例 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);
}

我會建議loop-unrolling

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 來檢查它們的“減少”、“增加”等!

鑒於您的所有條件,我真的想不出更好的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM