作为一个家庭作业问题,我正在从stdin读取十进制int,将其转换为另一个基础(也是从stdin提供)并将其打印到屏幕上。
这是我到目前为止所得到的:
#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,而简单的数学运算符和printf()/ getchar()/ scanf() - 没有函数,数组或指针。感谢。
答案 0 :(得分:3)
(删除了帖子的原始部分,因为它不是解决方案)
然后我能看到的唯一解决方案是执行你现在拥有数字的次数的循环。
首先,你计算所有数字直到你到达最后,然后打印出来。
然后你取原始值+基数并再次开始分割,直到你达到第二个“最高值”数字。打印出来。
这是一个双循环,你计算两次,但你不使用额外的存储空间。
答案 1 :(得分:3)
这是一个很好的尝试,也是一个很好的措辞问题。如果我们有更多的人以这种明确的方式提问:
这些限制似乎是人为的。我想你还没有在类中学过函数,数组,指针等,但我认为这个问题并不是没有函数和/或数组就可以优雅地解决。
无论如何,你可以这样做:
curr := base
pow := 1
while num / curr >= 1 do:
curr := curr * base
pow := pow + 1
while pow >= 1:
pow := pow - 1
print floor(num / base ** pow)
num := mod(num, base ** pow)
基本上,您要计算第一个循环中需要多少位数,然后再按正确的顺序打印数字。
您的代码的一些特定问题。我理解这是C课程的开始,但是现在知道这些问题比从未意识到这些问题更好:
printf("please enter a positive number to convert: ");
在此之后您应该添加fflush(stdout)
以确保在调用scanf()
之前显示输出。默认情况下,stdout
在许多系统上都是行缓冲的,因此在程序等待输入之前可能不会出现提示。
printf("please enter the base to convert to: ");
与上述相同。
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
你假设是ASCII字符集。这不一定是真的。但是没有数组或指针,就没有简单的方法来打印与10...
对应的字母表。此外,您的代码可能会为base > 36
打印奇怪的字符。
您还应该意识到安全使用scanf()
非常困难。希望您以后能够学到更好的获取方式。
答案 2 :(得分:1)
在一个循环中,您可以计算位数和big_base 在第二个循环中,您可以输出从最重要的数字开始的数字,如下所示:
n = 1020,3个十六进制数字,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
答案 3 :(得分:1)
问题的解决方案是以递归方式执行问题:
void my_putnbr_base(int num, int base)
{
int start;
int remainder;
remainder = num % base;
start = (num - remainder) / base;
if (start != 0)
my_putnbr_base(start, base);
if (remainder >= 10)
printf("%c", remainder + 55);
else
printf("%d", remainder);
}
你的作业是否指定它只适用于正数?如果没有,则很容易包含负数处理:
void my_putnbr_base(int num, int base)
{
int start;
int remainder;
if (num < 0)
{
putchar('-');
my_putnbr_base(-num, base);
}
else
{
remainder = num % base;
start = (num - remainder) / base;
if (start != 0)
my_putnbr_base(start, base);
if (remainder >= 10)
printf("%c", remainder + 55);
else
printf("%d", remainder);
}
}
@arno:这是真的,因为例程是使用ASCII表。如果我们想要一些灵活的东西,我们需要参数的基础。例如:
>> my_putnbr_base(4242, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
39U
>> my_putnbr_base(42, "0123456789ABCDEF")
2A
这实现了示例:
void my_putnbr_base(int num, char *base)
{
int start;
int remainder;
int len;
len = strlen(base);
if (num < 0)
{
putchar('-');
my_putnbr_base(-num, base);
}
else
{
remainder = num % len;
start = (num - remainder) / len;
if (start != 0)
my_putnbr_base(start, base);
printf("%c", base[remainder]);
}
}
我希望它能解决你的问题!
编辑:我没有正确阅读^^你不允许使用函数,所以递归是不可能的......这是一种交互方式,你可以把它放在一个main()中。您可以通过添加负数处理和灵活的基础来改进此代码,如我所示:)
int my_putnbr_base_it(int num, int base)
{
unsigned int quotient = 1;
unsigned int remainder;
while ((num / quotient) >= base)
quotient *= base;
while (quotient)
{
if ((remainder = (num / quotient) % base) < 10)
printf("%d", remainder);
else
printf("%c", 55 + remainder);
quotient /= base;
}
return (0);
}
希望它现在能解决所有问题!
答案 4 :(得分:0)
您可以重写计算每个数字的代码片段以充当状态机。它将以初始状态开始并计算位数,然后将状态更改为“打印第N位”以打印最高位数,然后更改状态以进入较低位数等,直到它进入最终州。在循环中运行它将以正确的顺序输出所有数字。
答案 5 :(得分:0)
你可以使用两个循环。第一个保持产生基数的功率,直到它找到大于输入数的功率。第二个从这里开始(或者更确切地说,之前是一个幂)并且返回到基数^ 0(即1)以首先计算最重要的输出数字。
未经测试的伪代码:
// Determine highest power, don't actually need "power" it's just there for illustration
power = 0;
baseraisedtopower = 1;
while (baseraisedtopower <= input)
{
baseraisedtopower *= base;
power++;
}
// Go back one step, could have saved previous result
baseraisedtopower /= base;
power--;
// Output
while (input > 0)
{
// Integer division, truncate
quotient = input / baseraisedtopower;
printf("%c", quotient + 55);
input -= quotient * baseraisedtopower;
baseraisedtopower /= base;
power--;
}
答案 6 :(得分:0)
您可以试试这种方法。 这更像是一个概念证明,你仍然需要处理一些特殊情况,但是,嘿,那是你的功课:)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, base, remainder, quotient;
int divider;
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;
}
// First get the highest divider
divider = base;
while ( num / divider > base ) {
divider *= base;
}
do {
// Get the highest digit
remainder = num / divider;
// And update num accordingly
num -= remainder * divider;
divider /= base;
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
} while ( divider );
printf("\n");
return 0;
}
答案 7 :(得分:0)
有趣的任务,你有作为一个功课。 我是初学者程序员,我试图解决这个问题。
以下代码正在运行(我没有经过多少测试,显然正在运行)。我相信这不是最佳和最佳的解决方案,但这是我唯一能想到的。它应该适用于任何基础。不幸的是,它不会转换10-> A,11-> B等:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int nr,base,res,tp,tpb,tpbt,r,rnr,lp,lpt,i;
float baset,rt;
/** Read number */
printf("nr=");
scanf("%d",&nr);
/** Read base */
printf("base=");
scanf("%d",&base);
/** Returning result */
res=0;
/** Test if number is positive
and base is bigger than 2 */
if(nr<0||base<2){
/** Error */
res=1;
}
else{
/** Determine how many
digits are necessary */
lp=0;
baset=base;
while(baset>1){
lp++;
baset/=10;
}
/** Determine full power
of 10 when r has length of lp */
tpb=1;
while((lp--)>0){
tpb*=10;
}
/** Power of ten that will be
incremented */
tp=0;
/** Converted number (will be printed
as the result) */
rnr=0;
/** Algorithm */
while(nr>0){
r=nr%base;
nr/=base;
rt=r;
/** Temporary lp for
r */
lpt=0;
while(rt>1){
lpt++;
rt/=10;
}
/** Temporary tpb for
lpt */
tpbt=tpb;
for(i=0;i<lpt;i++){
tpbt/=10;
}
/** Build number */
rnr+=r*pow((double)(tpbt),(double)(tp++));
}
}
/** Show number */
printf("number is: %d \n",rnr);
return (res);
}
答案 8 :(得分:0)
根据建议,解决这个问题的方法是保持打印最后一个数字,并为每个数字重复循环。我通过保存先前的商和我每次到达时打印(然后重新设置数字并重新开始)来跟踪打印条件,然后将其重置为之前的那个。听起来很复杂,但对代码的更改很简单。循环的停止条件是当我连续2次打印时,因为大部分时间它只计算商/余数并且不打印任何内容,当连续打印2位数时,它就是最后两位。无论如何,这是代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, saved, base, remainder;
int quotient, prev_q, stop_q, just_printed;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
saved = num;
remainder = quotient = prev_q = just_printed = 1;
stop_q = 0;
// validate input
if (num <= 0 || base <= 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// divide
while (1) {
remainder = num % base;
quotient = num / base;
num = quotient;
// print if it's the last number and reset num to the next
if (quotient == stop_q) {
if (remainder >= 10) { printf("%c", remainder + 55); }
else { printf("%d", remainder); }
// if 2 consecutive printing occur, this means it's time to end this
if (just_printed) { break; }
// next time print when hitting the previous quotient
stop_q = prev_q;
// reset the number to the original value
num = saved;
just_printed = 1;
} else {
just_printed = 0;
}
prev_q = quotient;
}
printf("\n");
return 0;
}
感谢所有投入的人!
答案 9 :(得分:0)
我们可以使用递归函数来反转数字的顺序:
我们需要这些库中的一些数学函数-stdlib.h
和math.h
int reverse(int x)
{
if(abs(x)<=9)
{
return x;
}
else
{
return reverse(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
}
}
“ If语句”是递归函数的基本情况。
“ Else语句”乍看起来可能令人生畏,但实际上只是简单的算法。 floor(log10(abs(x)))
为我们提供了x的位数,因此((x%10)*(pow(10, (floor(log10(abs(x)))))))
只是根据所需的反向数字将数字的“一个”位数放到正确的位置。
为了更好地理解,我们举一个例子,让 123 为我们需要反转的数字。函数reverse
要做的第一件事是问自己 12 (reverse(x/10)
)的相反方向,以及第二次使用参数 12调用该函数时,它会问自己与 1 相反的问题,这将是我们函数的基本情况。它将以abs(1)<=9
的形式返回 1 ,现在将以((x%10)*(pow(10, (floor(log10(abs(x))))))
开头 2 ,然后返回 21 3 将以相同的开头。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int reverse(int x);
int main()
{
int x, revInt;
scanf("%d", &x); // input : 123
revInt = reverse(x);
printf("%d", revInt); // output : 321
return 0;
}