注:
较为简便的方法是用 整型(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 // 程序不能执行 起始与结束不为2 或者 10进制的 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()) { // q不空表示含有小数位 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 }
时间: 2024-10-01 06:42:53