进制转换( C++字符数组 )

2018-06-17 23:36:45来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

注:

    较为简便的方法是用 整型(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 }

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:复制实参的局限性

下一篇:C语言 Web实时消息后台服务器推送技术---GoEasy