簡體   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