注:
較為簡便的方法是用 整型(int)或浮點型(long、double 注意:該類型不一定能夠准確存儲數據) 來存放待轉換的數值,可直接取余得到每一位數值
較為穩定的方法是用 字符數組儲存待轉換的數值,這將能夠完整存儲數據,但是也相對於代碼較長
進制轉換只需要兩步: R -> 十 或者 十 -> R (R表示除十進制的任意進制,10表示十進制)
以下是較為完整的全部代碼,若是實現如何轉換的,主看:
void Ten_Other(char[],int,int,char[],int&); void Other_Ten(char[],int,int,char[],int&);
兩個函數的實現
1 #include <iostream> 2 using namespace std; 3 struct Node { 4 Node * Next; 5 int data; 6 }; 7 class Stack { // 先進後出,用於存放除得的余數,取棧元素的時候正好於計算的相反,參見 短除法取得的余數的逆序為二進制數 8 public: 9 Stack(); 10 ~Stack(); 11 char GetTop(); 12 bool Push(char); 13 bool Isempty(); 14 bool Pop(); 15 private: 16 Node * Head; 17 }; 18 class Queue { //先進先出,用於存放計算獲得的每一位上的數值,參見 位權展開法,正序 19 public: 20 Queue(); 21 ~Queue(); 22 char GetTop(); 23 bool Add(char); 24 bool Drop(); 25 bool Isempty(); 26 private: 27 Node * Head; 28 Node * Tail; 29 }; 30 31 void Ten_Other(char[],int,int,char[],int&); //數組指針,長度,轉換進制 10 ->x , 目標數組,組長 32 void Other_Ten(char[],int,int,char[],int&); //數組指針,長度,轉換進制 x ->10 , 目標數組,組長 33 void Run(char*,int,int,int,char*,int&); //重載數組,長度,當前數組進制,目標進制 34 void Show(char[],int); 35 void Create(char[],int&); 36 int main() { 37 38 bool flag = true; 39 const int max = 25; 40 char Arr[max]; // 作為原始數組 或 目標進制放入該數組中 41 int len=max; // 數組最大字符數據 也同時是目標數組的長度 42 while(flag) { 43 cout<<"請輸入您要轉換的進制(以 # 作為結束符):"; 44 Create(Arr, len); 45 cout<<"請輸入您剛輸入的進制數和目標進制數:"; 46 int start, end; 47 cin>> start>> end; 48 49 cout<<"進制轉換: "; 50 Show(Arr, len); 51 Run(Arr, len, start, end, Arr, len); 52 cout<<" -> "; 53 Show(Arr, len); 54 cout<<endl; 55 cout<<"輸入0 結束, 輸入1 繼續: " ; 56 cin>> flag; 57 } 58 59 delete[] Arr; 60 return 0; 61 } 62 void Create(char* m,int& len) { 63 char ch; 64 int i=0; 65 cin>> ch; 66 while( ch!='#') { 67 m[i++] = ch; 68 cin>> ch; 69 } 70 len = i; 71 } 72 void Show(char* m,int len) { 73 for(int i=0; i<len; ++i) 74 cout<<m[i]; 75 } 76 void Run(char* str,int length,int ton,int con,char* Arr,int& len) { 77 int AL; 78 if(ton==10) { // R -> 10 79 Ten_Other(str, length, con, Arr, AL); 80 } else if(con==10) { // 10 -> R 81 Other_Ten(str, length, ton, Arr, AL); 82 } else { 83 Other_Ten(str, length, ton, Arr, AL); // 先將原始進制轉化為10 進制 84 Ten_Other(Arr, AL, con, Arr, AL); //再將10 進制 轉化為目標進制 85 } 86 len = AL; 87 } 88 void Ten_Other(char* str,int length,int con,char* Array,int& AL) { 89 Stack s; 90 Queue q; //注: 本函數結束後自動析構 s q 91 int i=0, m=0, len=length; 92 double n=0; 93 while( str[i]!='.' && len!=0) { // 將整數存放在 m 中 94 m = (((int)str[i]-'0') + m)*10; /// 95 i++; 96 len--; 97 } 98 m = m / 10; // 注意:此時除以 10,因為上面的while中,對整數的末尾多乘了一次 99 if(len!=0) { //判斷是否有 . 有則將下標前置一個到小數點之後, 100 i++; 101 len--; 102 } 103 double tem=1; // 此處不能為int ,否則下面計算 n 所得的結果為整數:((int)(str[length-len]-48)) / tem,結果為整數 104 while( len>0) { // 將小數部分存放在 n 中 105 tem = 10 * tem; 106 n = ((int)(str[length-len]-48)) / tem + n; 107 len--; 108 } 109 // 開始轉換進制 m為整數部分, n為小數部分 110 while( m!=0) { // 整數用棧 111 tem = m % con; // tem為全局變量 112 m = m/con; 113 s.Push(tem); // tem可能大於9 ,即為十六進制數 114 } // 將取余所得的全部放入棧中 115 i = 5; // i 為全局變量 116 double dou=0; 117 while(i!=0 && n!=0) { // 對小數部分做五次運算 小數部分入隊 118 dou = n * con; 119 m = dou; //再次使用全局變量 tem ,當tem 中的內容不需要的時候可任意使用 120 q.Add(m); 121 n = dou - m; // 去掉整數部分再次執行計算小數 122 } // 取得小數部分的進制數,可能含有十六進制所對應的字母序列 123 124 // char Array[20]; // 將數據存放在 數組裡面 125 char ch; 126 i = 0; // 注: i++ 表示先用再加! 127 if( s.Isempty()==true) { // 判斷是否含有整數,沒有整數部分,應該放入 0,然後放 . 例如: 0 . 5124 128 Array[i++] = '0'; 129 } 130 while( !s.Isempty()) { // 棧不空,即棧含有數值,放入數組中 131 m = s.GetTop(); // 得到的是數值 132 if(m>=0 && m<=9) { // 通過上面的計算得到的數值都是在0 ~ 15 之間 133 ch = m + 48; // 45的ASCII碼為 字符 0 134 } else { 135 ch = m + 55; // 若 m = 10; 則因為 A ; 65 = 10 + 55; 136 } 137 Array[i++] = ch; 138 s.Pop(); // 將已訪問過得頭結點出棧,即刪除 139 } // 整數部分放完 140 if( !q.Isempty()) { // 隊列 q 不空,表示含有小數位,故需要小數點 “ . ”, 若無小數位,則不需要“ . ” 141 Array[i++] = '.'; 142 } 143 while( !q.Isempty()) { 144 m = q.GetTop(); // 得到的是數值 145 if(m>=0 && m<=9) { // 通過上面的計算得到的數值都是在0 ~ 15 之間 146 ch = m + 48; // 45的ASCII碼為 字符 0 147 } else { 148 ch = m + 55; // 若 m = 10; 則因為 A ; 65 = 10 + 55; 149 } 150 Array[i++] = ch; 151 q.Drop(); 152 } 153 154 AL = i; // 注意: 此時的 i 變成了數組的組長,所以將組長存放在 AL中 155 } 156 157 void Other_Ten(char* str,int length,int Other,char* Array,int& AL) { 158 Stack s; 159 Queue q; //注: 本函數結束後自動析構 s q 160 int i=0, len=length, Integer=0, m=0; 161 double Dicimal=0; // len為length的一份拷貝 Integer存放整數 Dicimal 小數 162 int tem=0; 163 while(str[i]!='.' && len!=0) { // 整數的數值入隊,不含小數點 164 tem = str[i]- 48; 165 if(str[i]>='A' && str[i]<='F') { //當為十六進制的時候 就不能夠 減去字符 0 的ascii碼而得到目標數值 166 tem = str[i]- 55; 167 } 168 q.Add( tem); 169 len--; 170 i++; 171 } // i 為隊長 len 為入隊後剩余的字符個數 172 173 while(i!=1) { // 不計算倒數第一位 174 m = q.GetTop(); //獲取頭結點 175 q.Drop(); //將頭結點出棧刪除 176 Integer = (m + Integer) * Other; 177 i--; 178 } 179 Integer = Integer + (int)q.GetTop(); // 計算最後一位,整個值加上最後一個值,得到整數部分的目標進制數 180 q.Drop(); 181 // 以上整數部分操作完畢 182 183 len--; // len--後,為-1,表str全為整數,為0,表剩余一個 ‘ . ’, 大於0,表含有小數點,且點後有數 184 while( len>0) { 185 m = str[length-len]- 48; 186 if( str[length-len]>='A' && str[length-len]<='F') { 187 m = str[length-len] - 65; 188 } 189 s.Push( m); // length-len,例如,共長8,小數位為3, 8-3=5,此時的str[5]為小數位第一個 190 len--; 191 } //將小數位全部入棧 192 193 while( !s.Isempty()) { // s不空表示含有小數位 194 m = s.GetTop(); 195 s.Pop(); // m 為全局變量,再次使用 196 Dicimal = (m + Dicimal) / Other; 197 } 198 199 // cout<<Integer+Dicimal<<"(D)"<<endl; 得到的數值,為了統一將其放入數組中 200 // 以下全部為了將數據放入數組中, 一開始未意識到,故此多了一些代碼段 201 i = 0; 202 if(Integer==0) { 203 Array[i++] = '0'; 204 } 205 while(Integer!=0) { // 將整型入棧 206 m = Integer % 10; // m 為整型 207 Integer = Integer / 10; 208 s.Push(m); 209 } 210 char ch; 211 while(!s.Isempty()) { // 將棧元素放入數組 212 ch = s.GetTop() + 48; 213 s.Pop(); 214 if( ch>'9') { // 判斷是否為十六進制數 215 ch = ch + 7; 216 } 217 Array[i++] = ch; 218 } 219 220 if(Dicimal!=0) { 221 Array[i++] = '.'; 222 } 223 224 while(Dicimal!=0) { 225 Dicimal = Dicimal * 10; 226 m = Dicimal; 227 Dicimal = Dicimal - m; 228 q.Add(m); 229 } 230 while(!q.Isempty()) { 231 ch = q.GetTop() + 48; 232 q.Drop(); 233 if( ch>'9') { // 判斷是否為十六進制數 234 ch = ch + 7; 235 } 236 Array[i++] = ch; 237 } 238 AL = i; 239 } 240 241 Stack::Stack() { 242 Head = new Node(); 243 Head->Next = NULL; 244 } 245 246 Stack::~Stack() { 247 Node * p; 248 while(Head) { 249 p = Head; 250 Head = Head->Next; 251 delete p; 252 } 253 } 254 char Stack::GetTop() { 255 if(Isempty()) { 256 return '\0'; 257 } else { 258 return Head->data; 259 } 260 } 261 bool Stack::Push(char ch) { 262 Node * pNew = new Node(); 263 pNew->data = ch; 264 pNew->Next = Head; 265 Head = pNew; 266 return true; 267 } 268 bool Stack::Pop() { 269 if(Isempty()) { 270 return false; 271 } else { 272 Node * tem = Head; 273 Head = Head->Next; 274 delete tem; 275 } 276 return true; 277 } 278 bool Stack::Isempty() { 279 return Head->Next==NULL; 280 } 281 282 Queue::Queue() { 283 Head = new Node(); 284 Head->Next = NULL; 285 Tail = Head; 286 } 287 Queue::~Queue() { 288 Node * p; 289 while(Head) { 290 p = Head; 291 Head = Head->Next; 292 delete p; 293 } 294 Tail = NULL; 295 } 296 char Queue::GetTop() { 297 if(Isempty()) { 298 return '\0'; 299 } else { 300 return Head->Next->data; 301 } 302 } 303 bool Queue::Add(char ch) { 304 Node * pNew = new Node(); 305 pNew->data = ch; 306 Tail->Next = pNew; 307 pNew->Next = NULL; 308 Tail = pNew; 309 return true; 310 } 311 bool Queue::Drop() { 312 if(Isempty()) { 313 return false; 314 } else { 315 Node * tem = Head; 316 Head = tem->Next; 317 delete tem; 318 } 319 return true; 320 } 321 bool Queue::Isempty() { 322 return Head==Tail; 323 }