笔试算法题(12):整数的string到int转换 & 两个栈实现队列

出题:将输入的表示整数的字符串转变为对应的整数值;

分析:

  • 每当右边增加一位,说明之前的sum应该高一个数量级,所以*10。由于这两个实现仅仅考虑正规的、正整数输入,所以需要一个Wrapper函数,其功能
    主要处理:符号判断(第一个字符是-,+或者直接是数字);非法输入判断(是否有非"0123456789"的字符存在);

  • 另外以string存在的整数极有可能是大整数,所以需要考虑int的溢出的情况,当然这已经超出本议题的范围,不做详细论述;

解题:


 1 int NonRecursiveStrInt(char *target) {
2 int sum=0;
3 char *index=target;
4 while(*index != ‘\0‘) {
5 sum*=10;
6 sum+=*index-‘0‘;
7 index++;
8 }
9 return sum;
10 }
11 int RecursiveStrInt(char *target, int sum) {
12 if(*target != ‘\0‘) {
13 sum*=10;
14 sum+=*target-‘0‘;
15 return RecursiveStrInt(target++, sum);
16 } else
17 {
18 return sum;
19 }
20 }
21 //一个更加robust的版本,可以处理负数,以及包含非数字字符的string的转换
22 int str2int(char *str) {
23 char *temp;bool isnegative=false;
24 int sum=0;
25
26 if(*str==‘-‘) {
27 isnegative=true;
28 temp=str+1;
29 } else
30 temp=str;
31
32 while(*temp!=‘\0‘) {
33 if(*temp<‘0‘ || *temp>‘9‘) {
34 printf("\nbad int");
35 return 0;
36 }
37
38 sum*=10;
39 sum+=*temp-‘0‘;
40 temp++;
41 }
42
43 if(isnegative)
44 sum=-sum;
45 return sum;
46 }
47
48
49 int main() {
50 char *target="-324g54s";
51 printf("\n%d", str2int(target));
52 return 0;
53 }

出题:要求使用两个堆栈结构实现队列

分析:

  • 后进先出的模式转变成先进先出,堆栈A负责加入元素,堆栈B负责弹出元素,两种情况下需要将A中的元素弹出并加入B,所有操作均按照堆栈的性质执行:当B
    空栈的时候,当A满栈的时候。第一种情况较为简单,检测到B空栈,则将A中元素弹出并加入B;第二种情况需要使用第三个辅助堆栈保存B原有的元素,处理完
    A中元素之后再将原有元素压入B栈,并且A中送过来的元素需要满足一定的数量限制,以保证B有足够的空间存储原有的元素;

  • 反过来如果要用两个队列实现一个堆栈,能想到的办法是:迭代使用一个队列保存最近压入的元素,迭代发生在弹出元素的时候;

解题:


  1 class MyStack {
2 private:
3 int *array;
4 int capability;
5 int length;
6 int head;
7 int tail;
8 public:
9 MyStack(int n=5): array((int*)malloc(sizeof(int)*n)), head(0),tail(0),capability(n), length(0) {}
10 ~MyStack() {delete [] array;}
11
12 bool isFull() {
13 if(length == capability) return true;
14 return false;
15 }
16 bool isEmpty() {
17 if(length == 0) return true;
18 return false;
19 }
20 int freeSlot() {
21 return capability-length;
22 }
23 void setBack() {
24 length=0;
25 }
26 /**
27 * head当前的指向位置是下一次将push的元素的
28 * */
29 bool push(int n) {
30 if(isFull()) return false;
31 array[head]=n;
32
33 head=(head+1)%(capability);
34 length++;
35 return true;
36 }
37 /**
38 * tail当前指向的位置是下一次将pop的元素的
39 * */
40 bool pop(int *n) {
41 if(isEmpty()) return false;
42 *n=array[tail];
43
44 tail=(tail+1)%(capability);
45 length--;
46 return true;
47 }
48
49 void showStack() {
50 int i=tail;
51 int temp=length;
52 printf("\ncurrent stack elements: \n");
53 while(temp>0) {
54 printf("%d, ",array[i++]);
55 temp--;
56 }
57 }
58 };
59 /**
60 * first用于接收新元素,second用于输出旧元素,
61 * assist用于辅助栈
62 * */
63 class MyQueue {
64 private:
65 MyStack *first;
66 MyStack *second;
67 MyStack *assist;
68 public:
69 MyQueue(int n=5): first(new MyStack(n)), second(new MyStack(n)), assist(new MyStack(n)) {}
70 bool push(int e) {
71 if(first->isFull()) {
72 /**
73 * freeSlot()可以知道stack中剩余的空位置
74 * */
75 int fs=second->freeSlot();
76 int temp=0;
77 /**
78 * 将second中的元素弹出并加入到assist中
79 *
80 * */
81 while(second->pop(&temp) && assist->push(temp));
82
83 /**
84 * 从first中的元素弹出并压入second中,注意
85 * 有个数限制
86 * */
87 int i=0;
88 while(i<fs && first->pop(&temp) && second->push(temp)) {
89 i++;
90 }
91
92 /**
93 * 将second原有的元素从assist中取回,由于之前经过严格
94 * 的个数计算,所以一定可以全数压回
95 * */
96 while(assist->pop(&temp) && second->push(temp));
97 /**
98 * setBack()函数可以将stack重置为0个元素
99 * */
100 assist->setBack();
101 }
102 if(first->push(e)) return true;
103 else return false;
104 }
105 bool pop(int *e) {
106 int temp=0;
107 if(second->isEmpty()) {
108 /**
109 * 当second为空的时候,将first中的元素弹出并压入
110 * 到second中,主要当second满栈的时候需要将最后
111 * 一个元素压回first
112 * */
113 while(first->pop(&temp) && second->push(temp));
114
115 if(second->isFull()) first->push(temp);
116 }
117 if(second->pop(e)) return true;
118 else return false;
119 }
120 };

时间: 2024-09-29 04:45:26

笔试算法题(12):整数的string到int转换 & 两个栈实现队列的相关文章

笔试算法题(23):数值整数次方 &amp; 最大对称子串

出题:数值的整数次方(不考虑溢出),实现函数double Power(double base, int exponent): 分析: 解法1:最简单的方法是使用直接的乘法运算,但是注意处理几种特殊情况:exponent为负数,base为0: 解法2:将exponent分解成2的不同次方相加的表达式,通过重复平方来最大程度的减少乘法运算的次数. 当然,也可以递归实现,当n为偶数时,a^n=a^(n/2) * a^(n/2):当n为奇数时,a^n=a^((n-1)/2) * a^((n-1)/2)

笔试算法题(04):实现 string &amp; memcpy &amp; strcpy &amp; strlen

出题:请实现给定String的类定义: 分析:注意检查标准类构造注意事项: 解题: 1 #include <stdio.h> 2 #include <string.h> 3 /** 4 * 检查是否需要构造函数 5 * 检查是否需要无参构造函数 6 * 检查是否需要成员变量(函数)私有 7 * 检查是否需要在构造函数预初始化成员变量 8 * 检查是否需要析构函数 9 * 检查是否需要虚拟析构函数 10 * 检查是否需要复制构造函数(参数为const) 11 * 检查是否需要赋值重载

笔试算法题(20):寻找丑数 &amp; 打印1到N位的所有的数

出题:将只包含2,3,5的因子的数称为丑数(Ugly Number),要求找到前面1500个丑数: 分析: 解法1:依次判断从1开始的每一个整数,2,3,5是因子则整数必须可以被他们其中的一个整除,如果不包含任何其他因子则最终的结果为1: 解法2:小丑数必然是某个大丑数的因子,也就是乘以2,3,或者5之后的值,所以可以利用已经找到的丑数来寻找下一个丑数,使用数组有序保存已经找到的丑 数,并且当前最大丑数值为M:用大于M/2的丑数乘以2得到M1,用大于M/3的丑数乘以3得到M2,用大于M/5的丑数

笔试算法题(07):还原后序遍历数组 &amp; 半翻转英文句段

出题:输入一个整数数组,判断该数组是否符合一个二元查找树的后序遍历(给定整数数组,判定其是否满足某二元查找树的后序遍历): 分析:利用后序遍历对应到二元查找树的性质(序列最后一个元素必定是根节点,从左向右第一个比根节点大的元素开始直到根节点之前的所有元素必定在右子树,之前的所有元素必定在左子树): 解题: 1 bool PostOrderCheck(int *array, int i, int j) { 2 /** 3 * 如快速排序一样,解决小子文件 4 * */ 5 if(j-i+1 ==

笔试算法题(06):最大连续子数组和 &amp; 二叉树路径和值

出题:预先输入一个整型数组,数组中有正数也有负数:数组中连续一个或者多个整数组成一个子数组,每个子数组有一个和:求所有子数组中和的最大值,要求时间复杂度O(n): 分析: 时间复杂度为线性表明只允许一遍扫描,当然如果最终的最大值为0表明所有元素都是负数,可以用线性时间O(N)查找最大的元素.具体算法策略请见代码和注释: 子数组的起始元素肯定是非负数,如果添加的元素为正数则记录最大和值并且继续添加:如果添加的元素为负数,则判断新的和是否大于0,如果小于0则以下一个元素作为起始元素重新开始,如果大于

笔试算法题(39):Trie树(Trie Tree or Prefix Tree)

出题:TRIE树 (Trie Tree or Prefix Tree): 分析: 又称字典树或者前缀树,一种用于快速检索的多叉树结构:英文字母的Trie树为26叉树,数字的Trie树为10叉树:All the descendants of a node have a common prefix of the sequence associated with that node, and the root is associated with the empty sequence. 由于不同的se

笔试算法题(34):从数字序列中寻找仅出现一次的数字 &amp; 最大公约数(GCD)问题

出题:给定一个数字序列,其中每个数字最多出现两次,只有一个数字仅出现了一次,如何快速找出其中仅出现了一次的数字: 分析: 由于知道一个数字异或操作它本身(X^X=0)都为0,而任何数字异或操作0都为它本身,所以当所有的数字序列都异或操作之后,所有出现两次的数字异或操作之后的结果都为0,则最后剩下的结果就是那个仅出现了一次的数字: 如果有多个数字都仅仅出现了一次,则上述的异或操作方法不再适用:如果确定只有两个数字只出现了一次,则可以利用X+Y=a和XY=b求解: 解题: 1 int findSin

笔试算法题(09):查找指定和值的两个数 &amp; 构造BST镜像树

出题:输入一个已经升序排序的数组和一个数字:要求在数组中查找两个数,这两个数的和正好等于输入的那个数字,输出任意一对数字就可以,要求时间复杂度是O(n): 分析:对于升序排序的数组{-i-j-k-m--},只有可能是i+m=j+k(j和k可能是同一个数),所以可以从两边往中间收缩而忽视其他交叉相加的情况: 解题: 1 void FindSumFactor(int *array, int length, int sum) { 2 int left=0, right=length-1; 3 whil

笔试算法题(08):输出倒数第K个节点

出题:输入一个单向链表,要求输出链表中倒数第K个节点 分析:利用等差指针,指针A先行K步,然后指针B从链表头与A同步前进,当A到达链表尾时B指向的节点就是倒数第K个节点: 解题: 1 struct Node { 2 int v; 3 Node *next; 4 }; 5 Node* FindLastKth(Node *head, int k) { 6 if(head==NULL) { 7 printf("\nhead is NULL\n"); 8 exit(0); 9 } 10 Nod