數制轉換
在計算機中經常面對不同數制的轉換問題,如將一個十進制數N轉換為d進制B。數制轉換的解決方法很多,其中一個簡單的轉換算法是重復下述兩步。直到N等於零為止。
x = N mod d
N = N div d
其中,N為需要轉換的十進制數,d為轉換后的進制,x值為轉換后各個數位上的數,div為整除運算,mod為求余運算。算法的運行過程為:第一次求出的x值為d進制數的最低位,最后一次求出的x值為d進制數的最高位,所以上述算法是從低位到高位順序產生d進制的各位,然后逆序輸出,因為它按“后進先出”的規律進行的,所以用棧這種結構處理最合適。根據這個特點,利用棧來實現上述數制轉換,即將計算過程種一次得到的d進制數碼按順序棧進棧。計算結束后,再返順序出棧,並按出棧順序打印輸出。這樣即可得到給定的十進制數對應的d進制數,由此可以得到數制轉換的算法。
實現代碼
利用順序棧實現數制轉換(以十進制轉換為二進制為例)
1 #include <stdlib.h> 2 #include <stdio.h> 3 #define MAXSIZE 1024 4 5 /*定義順序棧*/ 6 typedef int elemtype; 7 typedef struct SequenStack 8 { 9 elemtype data[MAXSIZE]; 10 int top; 11 }SequenStack; 12 13 /*判(順序棧)棧空*/ 14 SequenStack * Init_SequenStack() 15 { 16 SequenStack * S; 17 S = (SequenStack *)malloc(sizeof(SequenStack)); 18 19 if (S == NULL) 20 { 21 return S; 22 } 23 S->top = -1; 24 return S; 25 } 26 27 /* 判空棧(順序棧)*/ 28 int SequenStack_Empty(SequenStack * S) 29 { 30 if (S->top == -1) 31 { 32 return 1; 33 } 34 else 35 { 36 return 0; 37 } 38 } 39 40 /* 入棧(順序棧) */ 41 int Push_SequenStack(SequenStack * S, elemtype x) 42 { 43 if (S->top >= MAXSIZE-1) 44 { 45 return 0; 46 } 47 S->top++; 48 S->data[S->top] = x; 49 return 1; 50 } 51 52 /* 出棧(順序棧) */ 53 int Pop_SequenStack(SequenStack * S, elemtype * x) 54 { 55 if (S->top == -1) 56 { 57 return 0; 58 } 59 else 60 { 61 S->top--; 62 *x = S->data[S->top+1]; 63 return 1; 64 } 65 } 66 67 /* 進制轉換算法 */ 68 void SequenStackConversion(int N) 69 { 70 int x; 71 SequenStack * S = Init_SequenStack(); 72 while (N > 0) 73 { 74 Push_SequenStack(S, N % 2); 75 N = N / 2; 76 } 77 while (! SequenStack_Empty(S)) 78 { 79 Pop_SequenStack(S, &x); 80 printf("%d", x); 81 } 82 } 83 84 int main() 85 { 86 int N; 87 printf("Please enter the decimal number you want want to convert:\n"); 88 scanf("%d", &N); 89 printf("The converted binary number is:\n"); 90 SequenStackConversion(N); 91 }
實現結果:
利用鏈棧棧實現數制轉換(以十進制轉換為二進制為例)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 /*定義鏈棧*/ 5 typedef int elemtype; 6 typedef struct LinkedStackNode 7 { 8 elemtype data; 9 struct LinkedStackNode *next; 10 }LinkedStackNode, *LinkedStack; 11 LinkedStack top; 12 13 /*鏈棧的初始化*/ 14 LinkedStack Init_LinkedStack() 15 { 16 LinkedStack top = (LinkedStackNode *)malloc(sizeof(LinkedStackNode)); 17 18 if(top != NULL) 19 { 20 top->next = NULL; 21 } 22 return top; 23 } 24 25 /*判棧空*/ 26 int LinkedStack_Empty(LinkedStack top) 27 { 28 if (top->next == NULL) 29 { 30 return 1; 31 } 32 else 33 { 34 return 0; 35 } 36 37 } 38 39 /*入棧*/ 40 int Push_LinkedStack(LinkedStack top, elemtype x) 41 { 42 LinkedStackNode *node; 43 node = (LinkedStackNode *)malloc(sizeof(LinkedStackNode)); 44 45 if (node == NULL) 46 { 47 return 0; 48 } 49 else 50 { 51 node->data = x; 52 node->next = top->next; 53 top->next = node; 54 return 1; 55 } 56 57 } 58 59 /*出棧*/ 60 int Pop_LinkedStack(LinkedStack top, elemtype * x) 61 { 62 LinkedStackNode *node; 63 if (top->next == NULL) 64 { 65 return 0; 66 } 67 else 68 { 69 node = top->next; 70 *x = node->data; 71 top->next = node->next; 72 free(node); 73 return 1; 74 } 75 76 } 77 78 /*進制轉換*/ 79 void ListStackConversion(int N) 80 { 81 int x; 82 LinkedStack S = Init_LinkedStack(); 83 while (N > 0) 84 { 85 Push_LinkedStack(S, N % 2); 86 N = N / 2; 87 } 88 while (! LinkedStack_Empty(S)) 89 { 90 Pop_LinkedStack(S, &x); 91 printf("%d", x); 92 } 93 94 } 95 96 int main() 97 { 98 int N; 99 printf("Please enter the decimal number you want want to convert:\n"); 100 scanf("%d", &N); 101 printf("The converted binary number is:\n"); 102 ListStackConversion(N); 103 }
實現結果:
把順序棧和鏈棧兩種功能綜合在一起實現數制轉換(以十進制轉換為十六進制為例)
1 /* 進制轉換 */ 2 #include <stdlib.h> 3 #include <stdio.h> 4 #define MAXSIZE 100 /*定義順序棧的長度*/ 5 6 /*定義順序棧*/ 7 typedef int elemtype; 8 typedef struct SequenStack 9 { 10 elemtype data[MAXSIZE]; 11 int top; 12 }SequenStack; 13 14 /*定義鏈棧*/ 15 typedef int elemtype; 16 typedef struct LinkedStackNode 17 { 18 elemtype data; 19 struct LinkedStackNode *next; 20 }LinkedStackNode, *LinkedStack; 21 LinkedStack top; 22 23 /* 順序棧初始化 */ 24 SequenStack * Init_SequenStack() 25 { 26 SequenStack * S; 27 S = (SequenStack *)malloc(sizeof(SequenStack)); 28 29 if (S == NULL) 30 { 31 return S; 32 } 33 S->top = -1; 34 return S; 35 } 36 37 /*鏈棧的初始化*/ 38 LinkedStack Init_LinkedStack() 39 { 40 LinkedStack top = (LinkedStackNode *)malloc(sizeof(LinkedStackNode)); 41 42 if(top != NULL) 43 { 44 top->next = NULL; 45 } 46 return top; 47 } 48 49 /*判棧(順序棧)空*/ 50 int SequenStack_Empty(SequenStack * S) 51 { 52 if (S->top == -1) 53 { 54 return 1; 55 } 56 else 57 { 58 return 0; 59 } 60 } 61 62 /* 判棧(鏈棧)空 */ 63 int LinkedStack_Empty(LinkedStack top) 64 { 65 if (top->next == NULL) 66 { 67 return 1; 68 } 69 else 70 { 71 return 0; 72 } 73 74 } 75 76 /* 入棧(順序棧)*/ 77 int Push_SequenStack(SequenStack * S, elemtype x) 78 { 79 if (S->top >= MAXSIZE-1) 80 { 81 return 0; 82 } 83 S->top++; 84 S->data[S->top] = x; 85 return 1; 86 } 87 88 /* 出棧(順序棧) */ 89 int Pop_SequenStack(SequenStack * S, elemtype * x) 90 { 91 if (S->top == -1) 92 { 93 return 0; 94 } 95 else 96 { 97 S->top--; 98 *x = S->data[S->top+1]; 99 return 1; 100 } 101 } 102 103 /* 入棧(鏈棧) */ 104 int Push_LinkedStack(LinkedStack top, elemtype x) 105 { 106 LinkedStackNode *node; 107 node = (LinkedStackNode *)malloc(sizeof(LinkedStackNode)); 108 109 if (node == NULL) 110 { 111 return 0; 112 } 113 else 114 { 115 node->data = x; 116 node->next = top->next; 117 top->next = node; 118 return 1; 119 } 120 121 } 122 123 /* 出棧(鏈棧) */ 124 int Pop_LinkedStack(LinkedStack top, elemtype * x) 125 { 126 LinkedStackNode *node; 127 if (top->next == NULL) 128 { 129 return 0; 130 } 131 else 132 { 133 node = top->next; 134 *x = node->data; 135 top->next = node->next; 136 free(node); 137 return 1; 138 } 139 140 } 141 142 /* 使用順序方式進行進制轉換的函數 */ 143 void SequenStackConversion(int N) 144 { 145 int x; 146 SequenStack * S = Init_SequenStack(); 147 while (N > 0) 148 { 149 Push_SequenStack(S, N % 16); 150 N = N / 16; 151 } 152 while (! SequenStack_Empty(S)) 153 { 154 Pop_SequenStack(S, &x); 155 switch (x) 156 { 157 case 10: 158 printf("A"); 159 break; 160 case 11: 161 printf("B"); 162 break; 163 case 12: 164 printf("C"); 165 break; 166 case 13: 167 printf("D"); 168 break; 169 case 14: 170 printf("E"); 171 break; 172 case 15: 173 printf("F"); 174 break; 175 default: 176 printf("%d", x); 177 break; 178 } 179 } 180 } 181 182 /* 使用鏈棧方式進行進制轉換的函數 */ 183 void ListStackConversion(int N) 184 { 185 int x; 186 LinkedStack S = Init_LinkedStack(); 187 while (N > 0) 188 { 189 Push_LinkedStack(S, N % 16); 190 N = N / 16; 191 } 192 while (! LinkedStack_Empty(S)) 193 { 194 Pop_LinkedStack(S, &x); 195 switch (x) 196 { 197 case 10: 198 printf("A"); 199 break; 200 case 11: 201 printf("B"); 202 break; 203 case 12: 204 printf("C"); 205 break; 206 case 13: 207 printf("D"); 208 break; 209 case 14: 210 printf("E"); 211 break; 212 case 15: 213 printf("F"); 214 break; 215 default: 216 printf("%d", x); 217 break; 218 } 219 220 } 221 222 } 223 224 void function() 225 { 226 printf("-------------------------------------------\n"); 227 } 228 229 /* 主函數調用進制轉換函數 */ 230 int main() 231 { 232 int N, x; 233 printf("Please enter the decimal number you want want to convert:\n"); 234 scanf("%d", &N); 235 function(); 236 printf("Choose using sequential stack or list stack\n"); 237 printf("1:Sequential stack 2:list stack:\n"); 238 function(); 239 scanf("%d", &x); 240 printf("The converted binary number is:\n"); 241 switch (x) 242 { 243 case 1: 244 SequenStackConversion(N); 245 break; 246 case 2: 247 ListStackConversion(N); 248 break; 249 default: 250 printf("error"); 251 break; 252 } 253 254 return 0; 255 }
值得注意的是,當十進制轉換為十六進制的時候,需要考慮輸出現實大於9的十六進制位數,這里我們考慮可以使用switch開關實現。
實現結果:
數制轉換的算法實現是利用棧的“LIFO”(后進先出)特性的簡單例子。當然,也可以用數組實現,那樣空間復雜度會降低,但是用棧實現時,其邏輯過程更清楚。