第三十一天(1): 面试算法题

类类型:

class CMyString{
public:
	CMyString(char* pdata = NULL);
	CMyString(const CMyString & str);
	~CMyString(void);
private:
	char* m_pData;
}

定义一个赋值运算符重载–改进四点

CMyString& CMyString::operator = (const CMyString &str){
	if(this == &str)
		return *this;
	
	delete [] m_pData;
	m_pData = NULL;
	
	m_pData = new char[strlen(str.m_pData) + 1];
	strcpy(m_pData, str.m_pData);
	return this;
}

高级版

–考虑异常安全性( Exception safety )
(当内存分配失败时, 能确保CMyString不会被修改)
(先创建一个临时实例,后交换到原实例)

CMyString& CMyString::operator = (const CMyString &str){
	if(this != &str){
		CMyString strTemp(str);
		
		char* pTemp = strTemp.m_pData;
		strTemp.m_pData = m_pData;
		m_pData = pTemp;
	}
	return *this;
}		

数组与指针的区别

int GetSize(int data[]){
	return sizeof(data);
}
int _tmain(int argc, _TCHAR* argv[]){
	int data1[] = {1, 2, 3, 4, 5};
	int size1 = sizeof(data1);
	
	int* data2 = data1;
	int size2 = sizeof(data2);

	int size3 = GetSize(data1);
	
	printf("%d, %d, %d", size1, size2, size3);
}	

二维数组中的查找

bool Find(int* matrix, int rows, int columns, int number){
	bool found = false;
	if(matrix != NULL && rows > 0 && columns > 0){
		int row = 0;
		int column = columns - 1;
		while(row < rows && columns >= 0){
			if(matrix[row * columns + column] == number){
				found = true;
				break;
			}
			else if(matrix[row * columns + column] > number)
				column--;
			else
				row++;
		}
	}
	return found;
}

内存地址是否相同

int _tmain(int argc, _TCHAR* argv[]){
	char str1[] = "hello world";
	char str2[] = "hello world";

	char* str3 = "hello world";
	char* str4 = "hello world";

	if(str1 == str2)
		printf("aaa");
	else
		printf("bbb");
		
	if(str3 == str4)
		printf("ccc");
	else
		printf("ddd");

替换空格

将URL中特殊字符转换成服务器可以识别的字符

" " 的ASCII码是32,即十六进制的0x20, 因此空格替换为“%20”

  1. 覆盖修改在该字符串后面的内存
  2. 创建新的字符串,在此基础上替换
  • a. 把第一个指针指向字符串末尾,第二个指针指向替换后的字符串的末尾,
  • b. 依次复制字符串的内容,直到第一个指针碰到第一个空格
  • c. 把第一个空格替换成 ‘%20’ ,把第一个指针向前移动一格,第二个指针向前移动3格,
  • d. 依次向前复制字符串的字符,直到碰到空格,
  • e. 重复
// length 为字符串总容量
void ReplaceBlank(char string[], int length){
	if(string == NULL && length <= 0)
		return;
	
	// originalLength 为字符串 string 的实际长度
	int originalLength = 0;
	int numberOfBlank = 0;
	int i = 0;
	while(string[i] != '\0'){
		++ originalLength;
		
		if((string[i] == ' ')
			numberOfBlank ++;
			
		i++;
	}

	// newLength 为把空格替换成 ’%20‘ 之后的长度
	int newLength = originalLength + numberOfBlank * 2;
	if(newLength > length)
		return;
	
	int indexOfOriginal = originalLength;
	int indexOfNew = newLength;
	while(indexOfOriginal >= 0 && indexOfNew > indexOfOriginal){
		if(string[indexOfOriginal] == ' '){
			string[indexOfNew-- ] = '0';
			string[indexOfNew-- ] = '2';
			string[indexOfNew-- ] = '%';
		}
		else
			string[indexOfNew-- ] = string[indexOfOriginal];
		indexOfOriginal--;
	}
}		

链表

当插入一个结点,为新节点分配内存,内存分配不是在创建链表时一次性完成,而是每添加一个结点,分配一次内存,无闲置内存,所以空间效率高

struct ListNode{
	int m_nValue;
	ListNode * m_pNext;
};
末尾添加结点

向链表的末尾添加一个结点(pHead是指向指针的指针)
(避免结束了这个函数后,pHead 仍然是空指针)

void AddToTail(ListNode** pHead, int value){
	ListNode* pNew = new ListNode();
	pNew->m_nValue = value;
	pNew->m_pNext = NULL;

	if(*pHead == NULL)
		*pHead = pNew;
	else{
		ListNode* pNode = *pHead;

		while(pNode->m_pNext != NULL)
			pNode = pNode->m_pNext;
		
		pNode->m_pNext = pNew;
	}
}		
删除结点
void RemoveNode(ListNode** pHead, int value){
	if(pHead == NULL || *pHead == NULL)
		return;
	ListNode* pToBeDeleted = NULL;
	if((*pHead)->m_nValue == value){
		pToBeDeleted = *pHead;
		*pHead = (*pHead)->m_pNext;
	}
	else{
		ListNode* pNode = *pHead;
		while(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)
			pNode = pNode->m_pNext;
		if(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value){
			pToBeDeleted = pNode->m_pNext;
			pNode->m_pNext = pNode->m_pNext->m_pNext;
		}
		if(pToBeDeleted != NULL){
			delete pToBeDeleted;
			pToBeDeleted = NULL
		}
	}
}
从尾到头打印链表
void PrintListReversely_Iteratively(ListNode* pHead){
	stack<ListNode* > nodes;
	ListNode* pNode = pHead;
	while(pNode != NULL){
		nodes.push(pNode);
		pNode = pNode->m_pNext;
	}
	while(!nodes.empty()){
		pNode = nodes.top();
		printf("%d\t", pNode->m_nValue);
		nodes.pop();
	}
}	
// 用递归来实现
void PrintListReversingly_Reversively(ListNode* pHead){
	if(pHead != NULL){
		if(pHead->m_pNext != NULL)
			PrintListReversingly_Reversively(pHead->m_pNext);
		printf("%d\t", pHead->m_nValue);
	}
} 
//可能导致函数调用栈溢出
发布了182 篇原创文章 · 获赞 101 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/lancecrazy/article/details/100922064