繁体   English   中英

优化转换算法

[英]Optimizing conversion algorithm

我最近一直在做我一直在读的一本书的练习。 任务是创建一个程序,以二进制、八进制和十六进制等价形式打印 1-256 之间的所有数字。 我们只应该使用到目前为止在本书中学到的方法,这意味着只使用 for、while 和 do..while 循环、if 和 else if 语句、将整数转换为 ASCII 等价物和一些更基本的东西(例如 cmath 和伊曼尼普)。

所以经过一些工作,这是我的结果。 然而,它是凌乱的、不优雅的和模糊的。 有没有人有任何建议来提高代码效率(或优雅......:P)和性能?

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

int main()
{
int decimalValue, binaryValue, octalValue, hexadecimalValue, numberOfDigits;
cout << "Decimal\t\tBinary\t\tOctal\t\tHexadecimal\n\n";
for (int i = 1; i <= 256; i++)
{
    binaryValue = 0;
    octalValue = 0;
    hexadecimalValue = 0;
    if (i != 0) 
    {
    int x, j, e, c, r = i, tempBinary, powOfTwo, tempOctal, tempDecimal;
    for (j = 0; j <=8; j++) //Starts to convert to binary equivalent
    {
        x = pow(2.0, j);
        if (x == i)
        {
              powOfTwo = 1;
              binaryValue = pow(10.0, j);
              break;
        }
        else if (x > i)
        {
              powOfTwo = 0;
              x /= 2;
              break;
        }
    }
    if (powOfTwo == 0)
    {
    for (int k = j-1; k >= 0; k--)
    {
        if ((r-x)>=0)
        {
           r -= x;
           tempBinary = pow(10.0, k);
           x /= 2;
        }
        else if ((r-x)<0)
        {
           tempBinary = 0;
           x /= 2;
        }
        binaryValue += tempBinary;
    }
    } //Finished converting
    int counter = ceil(log10(binaryValue+1)); //Starts on octal equivalent
    int iter;
    if (counter%3 == 0)
    {
       iter = counter/3;
    }
    else if (counter%3 != 0)
    {
       iter = (counter/3)+1; 
    }
    c = binaryValue;
    for (int h = 0; h < iter; h++)
    {
        tempOctal = c%1000;
        int count = ceil(log10(tempOctal+1));
        tempDecimal = 0;
        for (int counterr = 0; counterr < count; counterr++)
        {
            if (tempOctal%10 != 0)
            {
                 e = pow(2.0, counterr);
                 tempDecimal += e;
            }
            tempOctal /= 10;
        }
        octalValue += (tempDecimal * pow(10.0, h));
        c /= 1000;
    }//Finished Octal conversion
    cout << i << "\t\t" << binaryValue << setw(21-counter) << octalValue << "\t\t";
    int c1, tempHex, tempDecimal1, e1, powOf;
    char letter;
    if (counter%4 == 0)//Hexadecimal equivalent
    {
       iter = counter/4;
    }
    else if (counter%4 != 0)
    {
       iter = (counter/4)+1;
    }
    c1 = binaryValue;
    for (int h = 0, g = iter-1; h < iter; h++, g--)
    {
        powOf = g*4;
        if (h == 0)
        {
              tempHex = c1 / pow(10.0, powOf);
        }
        else if (h > 0)
        {
             tempHex = c1 / pow(10.0, powOf);
             tempHex %= 10000;
        }
        int count = ceil(log10(tempHex+1));
        tempDecimal1 = 0;
        for (int counterr = 0; counterr < count; counterr++)
        {
            if (tempHex%10 != 0)
            {
                 e1 = pow(2.0, counterr);
                 tempDecimal1 += e1;
            }
            tempHex /= 10;
        }
        if (tempDecimal1 <= 9)
        {
        cout << tempDecimal1;
        }
        else if (tempDecimal1 > 9)
        {
        cout << char(tempDecimal1+55); //ASCII's numerical value for A is 65. Since 10-15 are supposed to be letters you just add 55
        }
    }
    cout << endl;
    }
}
system("pause");
return 0;
}

任何改进建议将不胜感激。

您已经涵盖了“iomanip”,这表明您已经涵盖了“iostream”。

如果是这种情况,请查看以下内容:

#include <iostream>
#include <iomanip>
using namespace std;

int x = 250;
cout << dec << x << " " 
     << oct << x << " "
     << hex << x << "\n"
     << x << "\n";       // This will still be in HEX

Break out the functions for each output type, then loop through the integer list and output each in turn by calling the function for each different format.

for (int i = 1; i <= 256; ++i)
{
  printBin(i);
  printHex(i);
  printOct(i);
}

根本问题是这么长的 function 需要重构以更加模块化。 想象一下,您正在编写代码供其他人使用。 他们怎么称呼你的main 他们如何理解每一段代码在做什么? 他们不能。 如果您将具有特定工作的代码的每个部分都作为 function 进行调用,那么更容易理解其意图,并在以后重用。

您是否考虑过编写适用于任何基础的通用 function?

将非负数转换为通用基数很简单...您只需要计算number % base并获得最低有效位,然后将number除以base并重复以获得其他数字...

std::string converted_number;
do {
    int digit = number % base;
    converted_number = digits[digit] + converted_number;
    number = number / base;
} while (number != 0);

一旦你有一个通用的转换 function 然后解决你的问题很容易......只需使用 base=2、8 和 16 调用它以获得你需要的字符串结果。

我的回答可能有点讽刺,但是

 printf ("%u %o %x \n", value, value, value);

将为八进制和十六进制版本解决问题;)

对于二进制版本,我会使用初始化为 256 的标志,并使用 AND 运算符将其与您的数字进行比较。 如果为真,则打印 1,如果不是,则打印 0。然后将标志除以 2。 重复直到标志为 1。

从 integer 转换为二进制的伪代码

int flag = 256
do 
{
if (flag && value)
print "1"
else
print "0"
flag = flag >> 1 // aka divide by two, if my memory serves well
} while flag > 1

对于八进制和十六进制值,我有点生疏,但环顾四周应该会引导您找到您可能会适应的样本

为什么让它变得比实际更难。

for (int i = 1; i <= 256; ++i)
{
    std::cout << std::dec << i << "\t" << std::oct << i << "\t" << std::hex << i << std::endl;
}

尝试这个

using namespace std;

template <typename T>
inline void ShiftMask(T& mask) {
    mask = (mask >> 1) & ~mask;
}

template < typename T >
std::ostream& bin(T& value, std::ostream &o)
{
    T mask = 1 << (sizeof(T) * 8 - 1);

    while (!(value & mask) && (mask != 0)) ShiftMask(mask);

    while (mask) {
        o << (value & mask ? '1' : '0');
        ShiftMask(mask);
    }

    return o;
}

int main(void) {
  for (int i=0; i<256;i++) {
    bin(a, std::cout);
    cout << " " << oct << i;
    cout << " " << dec << i;
    cout << " " << hex << i;
    cout << ""
  }
}

也许是这样的?

#include "stdio.h"
int main(){
    char Chars[16]= {48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70};
    for(int n = 1;n != 256; n++)
    {
        {//decimal
            printf("%i\t", n); 
        }
        {//Hexadecimal
            char L, R;
            R = (n & 0x0F) >> 0;
            L = (n & 0xF0) >> 4;
            printf("%c%c\t", Chars[L], Chars[R]);
        }
        {//Octal
            char L, M, R;
            R = (n & 0x07) >> 0;
            M = (n & 0x38) >> 3;
            L = (n & 0xC0) >> 6;
            printf("%c%c%c\t", Chars[L], Chars[M], Chars[R]);
        }
        {//Binary
            char B0, B1, B2, B3, B4, B5, B6, B7;
            B0 = (n & 0x01) >> 0;
            B1 = (n & 0x02) >> 1;
            B2 = (n & 0x04) >> 2;
            B3 = (n & 0x08) >> 3;
            B4 = (n & 0x10) >> 4;
            B5 = (n & 0x20) >> 5;
            B6 = (n & 0x40) >> 6;
            B7 = (n & 0x80) >> 7;
            printf("%c%c%c%c%c%c%c%c\n", Chars[B0], Chars[B1], Chars[B2], Chars[B3], Chars[B4], Chars[B5], Chars[B6], Chars[B7]);
        }
        printf("256\t100\t400\t100000000\n");
    }
}

暂无
暂无

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

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