[英]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
)直到只剩下一位数字。 我们以decreasing
和increasing
的形式存储到目前为止的数字信息2
表示真正递增/递减, 1
表示递增/递减, 0
表示不递增/递减。
在每一步中, a
是个位, b
是十位。 然后,我们根据a
和b
之间的比较来改变increasing
和decreasing
。
最后,应该很容易将increasing
和decreasing
的值变成你想要的最终答案。
注意: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.