程序员面试攻略读书笔记

1、C语言: 定义一个宏,比较a、b的大小,不要用大于、小于和IF运算符

通过移位运算来判定整数的正负性。

#include <iostream>  
using namespace std;  
  
#define MAX(A,B) (((A)-(B))>>31 ? (B) : (A))  
  
int main()  
{  
    int a = 10, b = 100;  
    cout << MAX(a, b) << endl;  
}

 

2、堆栈的实现。

#include "stdafx.h"
#include <iostream>
using namespace std;


template <typename T>
class Stack
{
public:
	Stack(){ head = NULL; }
	~Stack();
	void Push(T ele);
	void Pop();
	bool Empty() const;
	T Top() const;
private:
	struct Node 
	{
		T element;
		Node *pNext;
	};
	Node *head;
};


int main()
{
	Stack<int> s;

	for(int i = 1; i <= 10; i++)
		s.Push(i);
	while (!s.Empty())
	{
		cout<<s.Top()<<endl;
		s.Pop();
	}
}

template <typename T>
void Stack<T>::Push(T ele)
{
	Node *temp = (Node*)malloc(sizeof(Node));
	temp->element = ele;
	temp->pNext = head;
	head = temp;
}

template <typename T>
void Stack<T>::Pop()
{
	if (!Empty())
	{
		Node *temp = head;
		head = head->pNext;
		free(temp);
	}
}

template <typename T>
bool Stack<T>::Empty()const
{
	if (head != NULL)
		return false;
	else
		return true;
}

template <typename T>
T Stack<T>::Top()const
{
	if (!Empty())
		return head->element;
}

template <typename T>
Stack<T>::~Stack()
{
	while (head != NULL)
	{
		Node *temp = head;
		head = head->pNext;
		free(temp);
	}
}


3、删除特定的字符串
用C语言编写一个高效率的函数来删除字符串里的给定字符。这个函数的调用模型如下所示:
void RemoveChars(char str[], char remove[])
注意,remove中的所有字符都必须从str中删除干净。

void RemoveChars(char str[], char remove[])
{
	int arr[256] = {0};
	
	int len2 = strlen(remove);
	for(int i = 0; i < len2; i++)
		arr[remove[i]]++;


	int len1 = strlen(str);
	int write = 0;
	for (int read = 0; read < len1; read++)
	{
		if (arr[str[read]] == 0)
			str[write++] = str[read];
	}
	str[write] = '\0';
}


int main()
{
	char str[] = "Battle of the Vowels: Hawaii vs. Gronzy";
	char remove[] = "aeiou";

	RemoveChars(str, remove);

	cout<<str<<endl;
}


4、字符串的全排列

void  Permute(char str[], int curPos, int len)
{
	if (curPos == len)
	{
		cout<<str<<endl;
	}
	else
	{
		for (int i = curPos; i < len; i++)
		{
			swap(str[i], str[curPos]);
			Permute(str, curPos + 1, len);
			swap(str[i], str[curPos]);
		}
	}
}
int main()
{
	char str[] = "abc";
	Permute(str, 0 , strlen(str));
}


5、求字符串的全组合

//函数功能 : 从一个字符串中选m个元素   
//函数参数 : pStr为字符串, m为选的元素个数,vec为选中的   
//返回值 :   无  
void Combine_m(char *str, int m, vector<char> &vec)
{
	if (str == NULL || *str == '\0')
		return;

	if (0 == m) //递归终止条件   
	{
		for (size_t i = 0; i < vec.size(); i++)
			cout<<vec.at(i);
		cout<<endl;
		return;
	}
		//选择这个元素
		vec.push_back(*str);
		Combine_m(str + 1, m - 1, vec);
		//不选择这个元素 
		vec.pop_back();
		Combine_m(str + 1, m, vec);
}

//函数功能 : 求一个字符串的组合   
//函数参数 : pStr为字符串   
//返回值 :   无   
void Combine(char *str)
{
	int len = strlen(str);
	
	for (int i = 1; i < len; i++)
	{
		vector<char> vec;
		Combine_m(str, i, vec);
	}
}
int main()
{
	char *str = "abcd";
	Combine(str);
}


 

5、了解临时对象
C++中真正的临时对象是不可见的——它们不出现在源代码中。如果一个对象被创建,而又不是在堆上创建的,并且没有名字
,那这个对象就是临时对象。

临时对象通常出现在两种情况下:
(1)、为了使函数调用能够成功而进行的隐式类型转换。
(2)、函数返回对象时进行的隐式类型转换。

对非常量引用进行的隐式类型转换修改的却是临时对象。这就是为什么C++语言禁止为非常量引用产生临时对象。
而常量引用参数没有这个问途径,因为声明为const,编译器知道它们不会被改变。


任何时候看到常量引用参数时,就有创建临时对象与这个参数绑定的可能行。
任何时候只要看到函数返回对象,就会有一个临时对象被创建,稍后被销毁。


.返回值优化:返回带参数的构造函数而不是直接返回对象。

6、C++规定:每一个被重载的运算符必须至少要有一个参数属于用户自定义类型,所以我们不能在一个类里面重载
这样的运算符函数:operator+(int , int)。

7、构造函数为什么不能为虚函数?
虚函数的意思就是开启动态绑定,程序会根据对象的动态类型来选择要调用的方法。然而在构造函数运行的时候,这个对象的动态类型还不完整,
没有办法确定它到底是什么类型,故构造函数不能动态绑定。(动态绑定是根据对象的动态类型而不是函数名,在调用构造函数之前,这个对象
根本就不存在,它怎么动态绑定?)


8、面试例题:数立方体
有一个由小立方体按3×3×3方法构成的大立方体,它的长、宽、高都是3个小立方体。
请问:在这个大立方体的表面有多少块小立方体?
解决办法:先把没有出现在大立方体表面的小方块的数目统计出来,然后用大立方体里的小方块总数减去它。
即:大立方体表面的小立方体数目为3×3×3=27,内部没有出现的小立方体数目为2×2×2=8,所以大立方体的表面一定是27-1=26个小立方体。


现在,给你一个由小立方体按4×4×4方法构成的大立方体,请问:在这个大立方体的表面有多少块小立方体?
同理,4*4*4 - 2*2*2 = 64 - 8 = 56.


现在,请把你的解决方法推广到由你n×n×n个小方块堆放出来的大立方体上去,此时,大立方体的表面有多少个小立方块?
同理:出现在大立方体表面的小方块的数量应该是n*n*n - (n-2)*(n-2)*(n-2).


立方体是三维空间中长、宽、高等三维尺寸相等的物体。我们把四维空间中四维尺寸相等的物体称为“超立方体”。请计算出四维尺寸是你n*n*n*n的4D
超立方体表面的小立方块的数量。
 同理:n×n×n×n - (n-2)×(n-2)×(n-2)×(n-2).

把你的解决方案推广到i维空间,在一个n×n×n×n.......×n (i维)的超立方体表面有多少个i维超立方块?
同理:n的i次方 - (n-2)的i次方。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值