不使用数组或函数以相反顺序打印数字的数字
作为一个家庭作业问题,我正在努力从标准输入读取十进制整数,将其转换为不同的基数(也从标准输入提供)并将其打印到屏幕上。
这是我到目前为止所得到的:
#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、while、简单的数学运算符和 printf()/getchar()/scanf() - 没有函数、数组或指针。谢谢。
As a homework problem, I'm working on reading a decimal int from stdin, converting it to a different base (also provided from stdin) and printing it to the screen.
Here's what I've got so far:
#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;
}
This works great, only that the algorithm this uses calculates the converted numbers from least significant to most significant digit, thus printing it in reverse. So, for example, converting 1020 to hexadecimal ( 0x3FC ) will print CF3.
Is there a trick I could use to reverse these numbers to print in the correct order. I can only use if-else, while, simple math operators and printf()/getchar()/scanf() - no functions, arrays or pointers. thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
(在这里删除了帖子的原始部分,因为它不是解决方案)
然后我能看到的唯一解决方案是执行您现在拥有的数字次数的循环。
因此,首先计算所有数字,直到最后一个数字,然后打印它。
然后你取原始值+基数并再次开始除法,直到到达第二个“最高值”数字,然后打印它。
这是一个双循环,您将所有内容计算两次,但不使用额外的存储空间。
(removed original part of the post here, since it is not the solution)
Then the only solution I can see is to perform the loop that you have now the number of times that you have digits.
So, first you calculate all digits till you get to the last, and then print it.
Then you take the original value + base and start dividing again till you come to the second "highest value" digit, then print it.
It is a double loop and you calculate everything twice, but you don't use extra storage.
这是一个很好的尝试,也是一个措辞良好的问题。如果有更多人以如此清晰的方式提出问题就好了!
这些限制似乎是人为的。我猜你还没有在你的班级中学习过函数、数组、指针等,但我认为如果没有函数和/或数组,这个问题就无法优雅地解决。
无论如何,您可以这样做:
基本上,您正在计算第一个循环中需要多少位数字,然后以正确的顺序打印数字。
您的代码的一些具体问题。我知道这是 C 类的开始,但现在知道这些问题总比永远不会意识到它们要好:
您应该在此之后添加一个
fflush(stdout)
以确保输出出现在调用scanf()
之前。默认情况下,stdout
在许多系统上是行缓冲的,因此在程序等待输入之前可能不会出现提示。与上面相同。
您假设使用 ASCII 字符集。这不一定是真的。但如果没有数组或指针,就没有简单的方法来打印
10...
对应的字母。另外,您的代码可能会打印base > 的奇怪字符。 36。
您还应该意识到,安全地使用
scanf()
非常困难。希望您以后能学到更好的获取输入的方法。It's a good try, and well phrased question. If only we had more people asking questions in such a clear manner!
The restrictions seem artificial. I guess you haven't learned about functions, arrays, pointers etc., in your class yet, but I think this problem is not meant to be solved elegantly without functions and/or arrays.
Anyway, you can do something like this:
Basically, you are calculating how many digits you will need in the first loop, and then printing the digits in the correct order later.
Some specific issues with your code. I understand it's the beginning of a C class, but still, it's better to know of such issues now than to never realize them:
You should add an
fflush(stdout)
after this to make sure the output appears beforescanf()
is called. By default,stdout
is line buffered on many systems, so the prompt may not appear before your program waits for input.Same as above.
You're assuming ASCII character set. This need not be true. But without arrays or pointers, there's no easy way to print the alphabets corresponding to
10...
. Also, your code may print weird characters forbase > 36
.You should also be aware that it's very hard to use
scanf()
safely. Hopefully you will learn better ways of getting input later.在一个循环中,您可以计算位数和 big_base。
在第二个循环中,您可以输出从最高位开始的数字,如下所示:
n = 1020, 3 个十六进制数字, big_base = 16*16
第一步
1020 / (16*16) = 3
第二步
n = 1020- 3*(16*16) = 252
252 / (16) = 15,F
第三步
n = 252 - 15*16 = 12,C
In one loop you can calculate the number of digits and the big_base.
In a second loop you can output the digits starting from the most significant, like this:
n = 1020, 3 hex digits, 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
嘿 !我也认识我在学校一年级时做过的著名作业(@Epitech 学生:不要复制/粘贴以下代码,尝试提出自己的解决方案,这是为了您自己好^^)
您的解决方案问题是以递归方式执行该问题:
您的作业是否指定它只能处理正数?如果没有,很容易包含负数处理:
@arno:确实如此,因为示例代码使用的是 ASCII 表。如果我们想要真正灵活的东西,我们需要参数的基础。例如:
这实现了示例:
我希望它能解决您的问题!
编辑:我没有读正确^^你不允许使用函数,所以递归是不可能的...这是一种交互方式,你可以把它放在main()中。您可以通过添加负数处理和灵活的基数来改进此代码,正如我向您展示的:)
希望它现在可以解决所有问题!
Hey ! I recognize a famous homework I had in first year of my school too (@Epitech students : don't copy/paste the following code, try to come up with your own solution, it's for your own good ^^)
The solution to your problem is to perform the problem in a recursive way :
Does your homework specifies that it should only work with positives numbers ? If not, it's easy to include the negative numbers handling :
@arno : that's true, because the exemple code is using ASCII table. If we want something trully flexible we need the base in parameter. For example :
this implements the example :
I hope it solves your problem !
edit: I didn't read correctly ^^ You are not allowed to use functions, so recursion is out of the question... Here is an interative way, you can put this in a main(). You can improve this code by adding the negative numbers handling and flexible bases, as I showed you :)
Hope it solves everything now !
您可以重写计算每个数字的代码片段以充当状态机。它将从初始状态开始并计算位数,然后将状态更改为“打印第 N 位数字”以打印最高有效数字,然后更改状态以继续处理较低有效数字,依此类推,直到进入最终状态状态。在循环中运行它,您将按正确的顺序输出所有数字。
You could rewrite the piece of code calculating each number to behave as a state machine. It will start in the initial state and compute the number of digits, then change the state to "print the Nth digit" to print the most significant digit, then change the state to proceed to the less significant digits, etc until it eneters the final state. Running this inside a loop you will output all digits in proper order.
您可以使用两个循环。第一个不断生成基数的幂,直到找到大于输入数的幂。第二个从这里开始(或者更确切地说,之前的一个幂)并返回到base^0(即1)以首先计算最高有效的输出数字。
未经测试的伪代码:
You could use two loops. The first keeps generating powers of the base until it finds a power greater than the input number. The second starts from here (or rather, one power before) and works back to base^0 (i.e. 1) to compute the output digits most significant first.
Untested pseudo-code:
您可以尝试一下这种方法。
这更多的是一个概念证明,您仍然需要处理一些特殊情况,但是,嘿,这是您的作业:)
You can give a try at this approach.
It's more a proof of concept, you'll still need to handle some special case, but, hey, that's your homework :)
有趣的任务,你有作为家庭作业。
我是一名初学者程序员,我已经尝试解决这个任务。
以下代码正在运行(我没有进行大量测试,显然正在运行)。我确信这不是最佳的解决方案,但这是我能想到的唯一的办法。它应该适用于任何底座。不幸的是,它不会转换 10->A、11->B 等:
Interesting task, you've got as a homework.
I am a beginner programmer to, and I've tried to resolve this task.
The following code is working (I haven't tested a lot, apparently is working). I am sure it's not the optimal&best solution, but was the only thing I've could come up with. It should work with any base. Unfortunately it won't convert 10->A, 11->B, etc.:
根据建议,解决此问题的方法是继续打印最后一个数字并对每个数字重复循环。我通过保存之前的商并在每次到达时打印(然后重置数字并重新开始)来跟踪打印条件,然后将其重置为之前的商。听起来很复杂,但是对代码的更改很简单。我的循环停止条件是当我连续打印 2 次时,因为大多数时候它只会计算商/余数而不打印任何内容,而当连续打印 2 位数字时,它是最后两位。无论如何,这是代码:
感谢所有参与的人!
Based on what was suggested, the way to tackle this was to keep print the last number and repeat the loop for every digit. I kept track of the print condition by saving the previous quotient and printing when I got to it every time (then reseting the number and starting over), then reset it to the one before. Sounds complicated, but the change to the code was simple. My stop condition for the loop was when I had 2 consecutive prints, since most of the time it would just calculate quotient/remainder and print nothing, and when 2 digits print in a row, it's the last two. Anyway, here's the code:
Thanks to everyone who pitched in!
我们可以使用递归函数来反转数字的顺序:
我们需要这些库中的一些数学函数 -
stdlib.h
和math.h
' If 语句' 是递归函数的基本情况。
“Else 语句”乍一看可能看起来很吓人,但它实际上只是简单的算术。
Floor(log10(abs(x)))
给出 x 的位数,因此((x%10)*(pow(10, (floor(log10(abs(x) )))))))
只是根据所需的反转数字将数字的“个位”数字放到正确的位置。为了更好地理解,我们举个例子,让 123 成为我们需要反转的数字。函数
reverse
要做的第一件事就是询问自己 12 的倒数 (reverse(x/10)
),以及函数何时第二次使用参数 12 调用时,它会询问自己 1 的相反情况,现在这将是我们函数的基本情况。它将返回 1 作为abs(1)<=9
,现在 2 将使用((x%10 )*(pow(10, (floor(log10(abs(x))))))
它将返回 21 并且 3 将被添加到前面相同。We could use a recursive function to reverse the order of the digits of a number :
We'll need some mathematical functions from these libraries -
stdlib.h
andmath.h
'If statement' is the base case for the recursive function.
'Else statement' may look intimidating at first but it's actually just simple arithmetic.
floor(log10(abs(x)))
gives us the number of digits of x, so((x%10)*(pow(10, (floor(log10(abs(x)))))))
is just putting the 'ones' place digit of the number to its correct place in accordance with the desired reversed number.For better comprehension let's take an example, Let 123 be the number we need to reverse. The first thing that the function
reverse
will do is ask itself the reverse of 12 (reverse(x/10)
) and when the function is called for the second time with argument 12 it'll ask itself the reverse of 1, Now this will be the base case for our function. It'll return 1 asabs(1)<=9
, Now 2 will be prepended using((x%10)*(pow(10, (floor(log10(abs(x))))))
it then will return 21 and 3 will be prepended by the same.