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

Base representation of numbers - output is in reverse order

本文关键字:输出 顺序 表示 数字      更新时间:2023-10-16

我试图用基数表示一个正整数(每个基数都在范围2到16)它正在工作,但我得到的输出与所需的输出相反,例如"2"的二进制表示应该是10,但我正在得到"01"。这是我的代码

#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();
}

我希望你能给我一些建议。感谢

result % base将始终获取需要打印的最后一个字符。因此,我们需要以某种方式反转输出。

递归:
执行打印的递归函数可以反转输出。由于它是递归的,所以它使用堆栈作为堆栈。因此,我们的输出得到了一个LIFO排序
只需将您的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;
}

请注意,低基数中愚蠢的高数字可能会导致(嗯哼)堆栈溢出。

result >=0result < 16 一样,result += result<10?'0':'A'-10;能很好地将result转换为ascii

非递归:
对于非递归版本,这个怎么样?从背面填充"数组"(使用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;
}

首先计算出需要多少个数字,设置一个正确大小的矢量来存储它,然后从末尾向前写入每个数字。然后它获取一个指向数据的指针以便输出它

在操作中查看

在特定基数中输出数字时,这是一个常见问题。通过取除以基数的模数,可以得到最后一个(最低有效)数字。您应该为数字保留一个缓冲区,可以将每个数字放入其中,然后按相反的顺序输出缓冲区的内容。考虑以下示例:

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];

对于转换,最好维护一个查找表:

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];

编辑:如果您希望输出在字符串中而不是控制台中,可以使用字符串流:

// ...
while(number > 0)
{ 
// ...
}
stringstream ss;
for(i = buffer.size()-1; i >=0; --i)
    ss<< buffer[i];
string theString = ss.str();

请注意,您必须使用#include <sstream>才能定义它。

您正在反向打印数字:number%b从数字中提取最后一个以b为底的数字,但这是您打印的第一个数字。

要按正确的顺序打印数字,您必须以某种方式颠倒顺序,以便最后一个数字打印在最后。例如,您可以将数字添加到矢量或将其写入字符串,然后将其反转。

要获得正确顺序的数字,可以"向后"操作。首先找到超过数字的基数的最小幂,提取数字,然后用较低的幂继续。

// 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;
}

这不是很有效,因为每个数字需要两个除法。