启迪思维:栈应用
栈在软件开发中应用非常广泛(函数调用、进制转换、括号匹配问题),记得刚刚毕业那会找工作,面试一家公司,上机题就是写一个二进制转换十进制的方法,两个小时硬是没有写出来(当时太傻,不知道查询下java的api实现),更幼稚时自己当时和那个公司hr讲“在实际开发中,不会用这些知识,我有很好的代码编写能力,能不能让我和你们项目经理谈谈”,结果可想而知。从这次面试中也懂得一点常识,如果想让别人帮助你,请先展现自己的实力和靠谱的梦想,因某些客观的原因没有很好展示,请不要开口寻求帮助(让别人为难,也让自己难堪)。
一、逻辑分析
题目:利用栈的数据结构特点,将二进制转换为十进制数
分析:搞编程的MM和JJ都知道,二进制数是计算机数据的存储形式,它是由一串0和1组成的,每个二进制数转换成相应的十进制数方法如下:
公式:(XnXn-1……X3X2X1)2 = X1*2^0+X2*2^1+…+Xn*2^(n-1)
举例:0101 = 0X2^3+1X2^2+0X2^1+1X2^0
从上面一串复杂的公式可以看出来,数学是编程的基础,有些伪大师到处宣传英语和数学学习不好的人,也可以学好编程(能写代码和写好代码有着天壤之别),这个基本是忽悠人。当然也可以当做善意的谎言,千万别当真。
二、代码分析
1、二进制转换十进制代码:
如图分析:
代码分析:
1 /** 2 *根据输入的值初始化栈 3 */ 4 void Convert::InitStack(LinkStack<char> *stack){ 5 6 //接受用户输入值,学习编程都知道二进制是0和1数字, 7 //为什么不用int,请参考test和test1运行结果区别 8 char c; 9 std::cout<<"input binary:"<<std::endl; 10 std::cin >> c; 11 12 //判断是否是二进制数 13 while(c == '0' || c == '1'){ 14 //压入栈中 15 stack->Push(c); 16 //循环接受用户输入 17 std::cin >> c; 18 } 19 } 20 21 /** 22 *二进制转化十进制函数 23 */ 24 void Convert::BinToDec(){ 25 26 //初始化栈 27 LinkStack<char> stack; 28 InitStack(&stack); 29 30 //sum存放转化后的十进制,i记录每次2的几次方,初始值为0 31 //例如:1011二进制最后一位就是1X2^0 32 int sum = 0,i = 0; 33 //接受出栈元素的值 34 char e; 35 36 //判断栈是否为空 37 while(!stack.IsEmpty()){ 38 //元素出栈 39 stack.Pop(e); 40 //e是是char类型,需要通过ASCII值转化成int(0对应ASCII:48,1对应ASCII:49) 41 sum = sum + (e - 48) * pow(2,i); 42 //每次出栈一个元素,自动加1次方 43 ++i; 44 } 45 //输出转化后的十进制数 46 std::cout<<sum<<std::endl; 47 }
完整代码
Common.h
/* * Common.h * * Created on: May 17, 2012 * Author: sunysen */ #ifndef COMMON_H_ #define COMMON_H_ #include <iostream> #include "memory" #include "string" #include <math.h> #include "core/node/LNode.h" using namespace std; #endif /* COMMON_H_ */
Convert.h:
1 /* 2 * Convert.h 3 * 4 * Created on: May 20, 2013 5 * Author: sunysen 6 */ 7 8 #ifndef CONVERT_H_ 9 #define CONVERT_H_ 10 #include "core/common/Common.h" 11 #include "core/stack/LinkStack.h" 12 13 class Convert { 14 private: 15 /** 16 *根据输入值初始化栈 17 */ 18 void InitStack(LinkStack<char> *stack); 19 public: 20 /** 21 * 构造函数 22 */ 23 Convert(); 24 /** 25 *析构函数 26 */ 27 ~Convert(); 28 /** 29 *二进制转化十进制函数 30 */ 31 void BinToDec(); 32 33 34 void test(); 35 36 void test1(); 37 }; 38 39 #endif /* CONVERT_H_ */
Convert.cpp:
1 /* 2 * Convert.cpp 3 * 4 * Created on: May 6, 2013 5 * Author: sunysen 6 */ 7 8 #include "Convert.h" 9 10 Convert::Convert(){} 11 12 Convert::~Convert(){} 13 14 /** 15 *根据输入的值初始化栈 16 */ 17 void Convert::InitStack(LinkStack<char> *stack){ 18 19 //接受用户输入值,学习编程都知道二进制是0和1数字, 20 //为什么不用int,请参考test和test1运行结果区别 21 char c; 22 std::cout<<"input binary:"<<std::endl; 23 std::cin >> c; 24 25 //判断是否是二进制数 26 while(c == '0' || c == '1'){ 27 //压入栈中 28 stack->Push(c); 29 //循环接受用户输入 30 std::cin >> c; 31 } 32 } 33 34 /** 35 *二进制转化十进制函数 36 */ 37 void Convert::BinToDec(){ 38 39 //初始化栈 40 LinkStack<char> stack; 41 InitStack(&stack); 42 43 //sum存放转化后的十进制,i记录每次2的几次方,初始值为0 44 //例如:1011二进制最后一位就是1X2^0 45 int sum = 0,i = 0; 46 //接受出栈元素的值 47 char e; 48 49 //判断栈是否为空 50 while(!stack.IsEmpty()){ 51 //元素出栈 52 stack.Pop(e); 53 //e是是char类型,需要通过ASCII值转化成int(0对应ASCII:48,1对应ASCII:49) 54 sum = sum + (e - 48) * pow(2,i); 55 //每次出栈一个元素,自动加1次方 56 ++i; 57 } 58 //输出转化后的十进制数 59 std::cout<<sum<<std::endl; 60 } 61 62 /** 63 *展现接受输入值为char 64 */ 65 void Convert::test(){ 66 //接受用户输入值 67 char c; 68 std::cout<<"input binary:"<<std::endl; 69 std::cin >> c; 70 71 //循环接受用户输入0或者1字符 72 while('0' == c || '1' == c){ 73 std::cout<<c<<std::endl; 74 std::cin >> c; 75 } 76 } 77 /** 78 *展现接受输入值为int 79 */ 80 void Convert::test1(){ 81 //接受用户输入值 82 int c; 83 std::cout<<"input binary:"<<std::endl; 84 std::cin >> c; 85 86 //循环接受用户输入0或者1数字,但不能形成连续输入效果(11011011) 87 while(0 == c || 1 == c){ 88 std::cout<<c<<std::endl; 89 std::cin >> c; 90 } 91 }
三:环境
1、运行环境:Ubuntu 10.04 LTS+VMware8.0.4+gcc4.4.3;
2、开发工具:Eclipse+make
四:题记
1、上面的代码难免有bug,如果你发现代码写的有问题,请你帮忙指出,让我们一起进步,让代码变的更漂亮和更健壮;
2、我自己能手动写上面代码,离不开郝斌、高一凡、侯捷、严蔚敏等老师的书籍和视频指导,在这里感谢他们;
3、鼓励自己能坚持把更多数据结构方面的知识写出来,让自己掌握更深刻,也顺便冒充下"小牛";
4、运行上面的代码还需要在包含一个公共的头文件(Common.h)
欢迎继续阅读“启迪思维:数据结构和算法”系列