简体   繁体   English

数字的基本表示-输出顺序相反

[英]Base representation of numbers - output is in reverse order

I m trying to represent a positive integer in base(Each base is in the range 2 through 16) Its working but the output that I m getting is reverse of the required output for example the binary representation of '2' should be 10 but im getting '01'. 我正在尝试在base中表示一个正整数(每个base在2到16的范围内),但我得到的输出与所需输出相反,例如'2'的二进制表示形式应为10,但im得到“ 01”。 This is my code 这是我的代码

#include<iostream.h>
#include<conio.h>
#include<math.h>

int main(void)
{
    int b, number, i, result;
    cout << "Enter the the number "<< endl;
    cin >> number;

    if (number < 0)
    {
        cout << "Number is not valid, as it must be greater than or equal to 0 \n";
        system("PAUSE");
        return 0;
    }

    cout<<"Enter the base value"<< endl;
    cin >> b; 


    if(b < 2 || b > 16){
        cout << "Base is not valid.\n";
        system("PAUSE");
        return 0;    
    }

    cout << "The representation of the number with base " << b << " is" << endl;  

    while(number > 0)  //number in base 10
    {
        result = number%b; 
        number = number/b;
        i++;                    

        if (result == 10)
        {
            cout << "A";
        }
        if (result == 11)
        {
            cout<<"B";
        }
        else if (result == 12)
        {
            cout<< 'C';
        }
        else if( result == 13)
        {
            cout<<"D";
        }
        else if (result == 14)
        {
            cout << "E";
        }
        else if(result == 15)
        {
            cout << "F";
        }
        else {
            cout << result ;
        }

    }

    getch();
}

I would appreciate some suggestions. 我将不胜感激一些建议。 Thanks 谢谢

It's a common issue when outputting numbers in a specific base. 以特定基数输出数字时,这是一个常见问题。 By taking the modulus of the division by the base you get the last (least significant) digit. 通过将除法模除以基数,可以得到最后一位(最低有效位)。 You should maintain a buffer for the digits into which you can put each digit, then output the contents of the buffer in reverse order. 您应该为每个数字保留一个数字缓冲区,然后以相反的顺序输出该缓冲区的内容。 Consider the following example: 考虑以下示例:

vector<char> buffer;
while(number > 0)  //number in base 10
{
  result = number%b; 
  number = number/b;
  i++;                    

  if (result >= 10)
    buffer.push_back((char)(result-10)+'A');   // alphabet is contiguous in ascii,
                                               // so you don't need a huge if

  else
    buffer.push_back((char)result+'0');
}
for(i = buffer.size()-1; i >=0; --i)
    cout << buffer[i];

for the conversion, it's even better to maintain a lookup table: 对于转换,最好维护一个查找表:

const char *hextable = "0123456789ABCDEF";
vector<char> buffer;
while(number > 0)  //number in base 10
{
      result = number%b; 
      number = number/b;
      buffer.push_back(hextable[result]);
}

for(i = buffer.size()-1; i >=0; --i)
    cout << buffer[i];

EDIT: If you would like to have the output in a string instead of the console, you can use a stringstream: 编辑:如果您希望以字符串而不是控制台的形式输出,则可以使用stringstream:

// ...
while(number > 0)
{ 
// ...
}

stringstream ss;
for(i = buffer.size()-1; i >=0; --i)
    ss<< buffer[i];

string theString = ss.str();

note that you have to #include <sstream> in order to have it defined. 请注意,您必须#include <sstream>才能对其进行定义。

result % base will always grab the last character that needs to be printed. result % base将始终获取需要打印的最后一个字符。 Therefore, we need to reverse the output somehow. 因此,我们需要以某种方式反转输出。

Recursive: 递归:
A recursive function that does the printing can reverse the output. 执行打印的递归函数可以反转输出。 As it is recursive, it uses the stack as a, well, stack. 由于它是递归的,因此它将堆栈用作堆栈。 Thus we get a LIFO ordering with our output. 因此,我们得到了带有输出的LIFO订单。
Just replace your while loop with a call to this: 只需用以下调用替换while循环即可:

rec_print(int number, int base)
{
    rec_print(number/base, base);
    int result = number / base;
    if ( result <= 0) {return;}
    result += result<10?'0':'A'-10;
    cout << result;
    return;
}

just be aware that stupidly high numbers in low base may cause a (ahem) stack overflow. 请注意,低位的高位数字可能会导致(糟糕的)堆栈溢出。

result += result<10?'0':'A'-10; converts result to ascii quite nicely as long as result >=0 and result < 16 只要result >=0result < 16很好地将result转换为ascii

Non Recursive: 非递归:
How about this for a non-recursive version? 对于非递归版本呢? Fills an 'array' (using vector for runtime sizing) from the back and then prints it. 从背面填充“数组”(使用vector进行运行时大小调整),然后打印出来。

void print_number(int number, int base)
{
    int result;
    int number_of_digits = log(number)/log(base) +1;   //+1 because '/' truncates and we want to always round up.
    vector<char> output(number_of_digits+1); //vector<char> of the right size (+1 for null terminator)
    output[number_of_digits+1] = 0; //null terminate.
    while (number_of_digits--)
    {
        result = number % base;
        result += result<10?'0':'A'-10;
        output[number_of_digits] = result;
        number /= base;
    }
    std::cout << &output[0]<<endl;
}

Works out how many digits are needed first, sets up a vector of the correct size to store it then writes each digit in from the end towards the front. 首先计算出需要多少个数字,设置一个正确大小的向量来存储它,然后将每个数字从头到尾写入。 It then grabs a pointer to the data in order to output it. 然后,它获取指向数据的指针以进行输出。

See it in action 实际观看

You are printing the number in reverse: number%b extracts the last base-b digit from the number, but it's the first digit that your print. 您正在反向打印数字: number%b从数字中提取最后一个基数b,但它是您打印的第一个数字。

To print the digits in the right order you have to reverse the sequence somehow, so that the last digit is printed last. 要以正确的顺序打印数字,您必须以某种方式反转顺序,以便最后打印最后一个数字。 For example you could add the digits to a vector or write them in into a string, and the then reverse it. 例如,您可以将数字添加到向量中或将其写入字符串中,然后反转。

To get the digits in the proper order, you can work "backward". 要以正确的顺序获取数字,您可以“向后”工作。 First find the smallest power of the base that exceeds the number, extract the digit, and continue with lower powers. 首先找到超过数字的最小底数幂,提取数字,然后以较低的幂继续。

// Find the smallest power
w= 1;
while (w * b <= n)
{
  w*= b;
}

// Extract the digits
while (w > 0)
{
   digit= n / w;
   n-= digit * w;
   w/= b;
}

This is not so efficient as it takes two divisions per digit. 这不是很有效,因为每个数字需要两个除法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM