注:
較為簡便的方法是用 整型(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 }