俗话说的好,根基不稳,地动山摇,作为一名C/C++开发人员,基本功的扎实程度决定了职业高度,本篇将C/C++常见笔试题进行整理。
目录
1.1 vector中push_back和emplace_back的区别
1.STL
1.1 vector中push_back和emplace_back的区别
emplace_back() 函数是 C++11 新增加的,其功能和push_back()相同, emplace_back可以直接通过参数构建容器元素,省去了一次拷贝构造的调
#include<iostream>
#include <vector>
#include <string.h>
using namespace std;
// emplace_back() 函数是 C++11 新增加的,其功能和 push_back()相同, emplace_back可以直接通过参数构建
//容器元素,省去了一次拷贝构造的调
class ItemData
{
public:
// 无参数构造函数
ItemData() : m_iData(0), m_strData("")
{
std::cout << "call ItemData() " << this << std::endl;
}
//带参数构造函数
ItemData(int id, std::string strData) : m_iData(id), m_strData(strData)
{
std::cout << "call ItemData(int id, std::string strData) " << this << std::endl;
}
//拷贝构造
ItemData(const ItemData &t) : m_iData(t.m_iData), m_strData(t.m_strData)
{
std::cout << "call ItemData(const ItemData &t) " << this << std::endl;
}
//移动构造
ItemData(const ItemData &&t)
{
m_iData = std::move(t.m_iData);
m_strData = std::move(t.m_strData);
std::cout << "call ItemData(const ItemData &&t) " << this << std::endl;
}
//析构
~ItemData()
{
std::cout << "call ~ItemData() " << this << std::endl;
}
private:
int m_iData;
std::string m_strData;
};
void test1() {
std::cout << "----------------------- test1() ---------------------------" << std::endl;
vector<ItemData> vec;
vec.reserve(10);
std::cout << "------ push_back --------" << std::endl;
vec.push_back(ItemData(111, "hello"));
std::cout << "------ emplace_back --------" << std::endl;
vec.emplace_back(ItemData(222, "world"));
std::cout << "-------- finish -------- " << std::endl;
}
void test2() {
std::cout << "------------------------ test2() --------------------------" << std::endl;
vector<ItemData> vec;
vec.reserve(10);
std::cout << "------ push_back --------" << std::endl;
vec.push_back(ItemData(333, "stl"));
std::cout << "------ emplace_back --------" << std::endl;
vec.emplace_back(444, "vector");
std::cout << "-------- finish -------- " << std::endl;
}
void vector_test() {
test1();
std::cout << std::endl << std::endl;
test2();
}
int main() {
vector_test();
return 0;
}
1.2 vector清除内存
#include <iostream>
#include <vector>
using namespace std;
// 方法一:std::vector<int>().swap
void empty1(std::vector<int> &iVec) {
std::vector<int>().swap(iVec);
}
// 方法二:clear() + shrink_to_fit()
void empty2(std::vector<int> &iVec) {
iVec.clear();
iVec.shrink_to_fit();
}
// 方法三:std::move语义转移清空
void empty3(std::vector<int> &iVec) {
auto data = std::move(iVec);
}
// C++11增加接口shrink_to_fit()删除不存储数据的多余内存
void test1() {
std::vector<int> iVec;
iVec.push_back(111);
iVec.push_back(222);
iVec.push_back(333);
iVec.push_back(444);
iVec.push_back(555);
std::cout << iVec.size() << " " << iVec.capacity() << std::endl;
empty1(iVec);
std::cout << iVec.size() << " " << iVec.capacity() << std::endl;
}
void test2() {
std::vector<int> iVec;
iVec.push_back(111);
iVec.push_back(222);
iVec.push_back(333);
iVec.push_back(444);
iVec.push_back(555);
std::cout << iVec.size() << " " << iVec.capacity() << std::endl;
empty2(iVec);
std::cout << iVec.size() << " " << iVec.capacity() << std::endl;
}
void test3() {
std::vector<int> iVec;
iVec.push_back(111);
iVec.push_back(222);
iVec.push_back(333);
iVec.push_back(444);
iVec.push_back(555);
std::cout << iVec.size() << " " << iVec.capacity() << std::endl;
empty3(iVec);
std::cout << iVec.size() << " " << iVec.capacity() << std::endl;
}
int main(int argc, char *argv[])
{
test1();
test2();
test3();
return 0;
}
1.3 std::array
std::array是在栈上分配内存
#include <iostream>
#include <array>
using namespace std;
void test_array() {
std::array<int, 5> arr = { 1, 2, 3, 4, 5 };
std::cout << arr.size() << std::endl;
for (const auto & item : arr) {
std::cout << item << std::endl;
}
}
int main() {
test_array();
return 0;
}
2.排序
2.1 冒泡排序
#include<iostream>
using namespace std;
void show_arr(int arr[], int iLen) {
for (int i = 0; i < iLen; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
void bubbling_sort(int arr[], int iLen) {
int iTemp = 0;
for (int i = 0; i < iLen - 1; i++) {
for (int j = i + 1; j < iLen; j++) {
if (arr[i] > arr[j]) {
iTemp = arr[i];
arr[i] = arr[j];
arr[j] = iTemp;
}
}
}
}
void test_bubbling_sort() {
int arr[10] = {90, 18, 3, 56, 32, 45, 23, 21, 9, 51};
int iLen = sizeof(arr) / sizeof(arr[0]);
std::cout << "before sort:: ";
show_arr(arr, iLen);
bubbling_sort(arr, iLen);
std::cout << "afort sort:: ";
show_arr(arr, iLen);
}
int main() {
test_bubbling_sort();
return 0;
}
2.2 快速排序
#include <iostream>
#include <vector>
#include <unistd.h>
using namespace std;
void show_arr(int arr[], int iLen) {
for (int i = 0; i < iLen; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
void swap(int& a, int& b) {
int iTmp = a;
a = b;
b = iTmp;
}
void quick_sort(int iArr[], int iLow, int iHigh) {
if (iLow >= iHigh) {
return;
}
int iKey = 0;
iKey = iArr[iLow];
int i = iLow;
int j = iHigh;
while (i < j) {
while (iArr[i] <= iKey && i < iHigh) {
i++;
}
while (iArr[j] >= iKey && j > iLow) {
j--;
}
if (i >= j) {
break;
}
swap(iArr[i], iArr[j]);
}
swap(iArr[iLow], iArr[j]);
//show_arr(iArr, 10);
quick_sort(iArr, iLow, j - 1);
quick_sort(iArr, j + 1, iHigh);
}
void test_quick_sort() {
int arr[10] = {90, 18, 3, 56, 32, 45, 23, 21, 9, 51};
int iLen = sizeof(arr) / sizeof(arr[0]);
std::cout << "before sort:: ";
show_arr(arr, iLen);
quick_sort(arr, 0, iLen - 1);
std::cout << "afort sort:: ";
show_arr(arr, iLen);
}
int main(int argc, char *argv[])
{
test_quick_sort();
return 0;
}
2.3 堆排序
#include <iostream>
#include <vector>
#include <unistd.h>
using namespace std;
void show_arr(int arr[], int iLen) {
for (int i = 0; i < iLen; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
void swap(int& a, int& b) {
int iTmp = a;
a = b;
b = iTmp;
}
void build_max_heap(int iArr[], int n) {
if (n < 2) {
return;
}
//计算开始堆构建位置
int i = n / 2 - 1;
int left = 0;
int right = 0;
int iMax = 0;
while (i >= 0) {
left = 2 * i + 1;
right = 2 * i + 2;
iMax = iArr[left];
//有右子树时
if (right < n) {
if (iArr[right] > iArr[left] ) {
iMax = iArr[right];
}
}
if (iMax > iArr[i]) {
// 左子树大时父节点和左节点交换
if (iMax == iArr[left]) {
swap(iArr[i], iArr[left]);
}
else {// 右子树大时父节点和右节点交换
swap(iArr[i], iArr[right]);
}
}
i--;
}
}
// 从小到大排序,先构建大根堆,然后用第一个和最后一个交换, 最后一个就是最大值,跳过最后一个继续构建大根堆
// 然后用第一个和倒数第二个交换,倒数第二个就是第二大,跳过最后两个继续构建大根堆
void heap_sort(int iArr[], int iLen) {
if (!iArr || iLen < 0) {
return;
}
for (int i = iLen; i >= 1; i--) {
build_max_heap(iArr, i);
swap(iArr[0], iArr[i - 1]);
}
}
void test_heap_sort() {
int arr[10] = {90, 18, 3, 56, 32, 45, 23, 21, 9, 51};
int iLen = sizeof(arr) / sizeof(arr[0]);
std::cout << "before sort:: ";
show_arr(arr, iLen);
heap_sort(arr, iLen);
std::cout << "afort sort:: ";
show_arr(arr, iLen);
}
int main(int argc, char *argv[])
{
test_heap_sort();
return 0;
}
3.内存
3.1 实现memset函数
#include<iostream>
using namespace std;
void* my_memcpy(void* pDest, void* pSrc, unsigned int iCount) {
if (!pDest || !pSrc) {
return NULL;
}
char *pD = (char*)pDest;
char *pS = (char*)pSrc;
if (pD <= pS || pD >= (pS + iCount)) {
while (iCount--) {
*pD++ = *pS++;
}
}
else { //内存重叠处理
pD = (char*)pDest + iCount - 1;
pS = (char*)pSrc + iCount - 1;
while (iCount--) {
*pD-- = *pS--;
}
}
return pDest;
}
int main() {
char tmpBuf[128] = "111111222222333333444444";
char destBuf[128] = {0};
std::cout << "1 " << (char*)my_memcpy(destBuf, tmpBuf, 10) << std::endl;
std::cout << "2 " << destBuf << std::endl;
std::cout << "3 " << (char*)my_memcpy(tmpBuf + 5, tmpBuf, 10) << std::endl;
std::cout << "4 " << tmpBuf << std::endl;
return 0;
}
4.链表
2.1 冒泡排序
#include<iostream>
using namespace std;
struct Node {
int data;
Node* pNext;
};
//构建链表
void build_list(Node*& pHead) {
pHead = new Node;
pHead->data = 90;
Node* pNode1 = new Node;
pNode1->data = 18;
pHead->pNext = pNode1;
Node* pNode2 = new Node;
pNode2->data = 3;
pNode1->pNext = pNode2;
Node* pNode3 = new Node;
pNode3->data = 56;
pNode2->pNext = pNode3;
Node* pNode4 = new Node;
pNode4->data = 32;
pNode3->pNext = pNode4;
Node* pNode5 = new Node;
pNode5->data = 45;
pNode4->pNext = pNode5;
Node* pNode6 = new Node;
pNode6->data = 23;
pNode5->pNext = pNode6;
Node* pNode7 = new Node;
pNode7->data = 21;
pNode6->pNext = pNode7;
Node* pNode8 = new Node;
pNode8->data = 9;
pNode7->pNext = pNode8;
Node* pNode9 = new Node;
pNode9->data = 51;
pNode8->pNext = pNode9;
pNode9->pNext = nullptr;
}
//遍历链表内容
void show_list(Node* pHead) {
Node* tmp = pHead;
while (tmp) {
std::cout << tmp->data << " ";
tmp = tmp->pNext;
}
std::cout << std::endl;
}
//链表冒泡排序
void list_bubbling_sort(Node* pHead) {
if (!pHead) {
return;
}
Node* pDeal = pHead;
while (pDeal) {
Node* pBack = pDeal ->pNext;
while (pBack) {
if (pDeal->data > pBack->data) {
int iTemp = pDeal->data;
pDeal->data = pBack->data;
pBack->data = iTemp;
}
pBack = pBack->pNext;
}
pDeal = pDeal->pNext;
}
}
int main() {
Node* pHead = nullptr;
build_list(pHead);
show_list(pHead);
list_bubbling_sort(pHead);
show_list(pHead);
return 0;
}
2.2 逆序
#include<iostream>
using namespace std;
struct Node {
int data;
Node* pNext;
};
//构建链表
void build_list(Node*& pHead) {
pHead = new Node;
pHead->data = 90;
Node* pNode1 = new Node;
pNode1->data = 18;
pHead->pNext = pNode1;
Node* pNode2 = new Node;
pNode2->data = 3;
pNode1->pNext = pNode2;
Node* pNode3 = new Node;
pNode3->data = 56;
pNode2->pNext = pNode3;
Node* pNode4 = new Node;
pNode4->data = 32;
pNode3->pNext = pNode4;
Node* pNode5 = new Node;
pNode5->data = 45;
pNode4->pNext = pNode5;
Node* pNode6 = new Node;
pNode6->data = 23;
pNode5->pNext = pNode6;
Node* pNode7 = new Node;
pNode7->data = 21;
pNode6->pNext = pNode7;
Node* pNode8 = new Node;
pNode8->data = 9;
pNode7->pNext = pNode8;
Node* pNode9 = new Node;
pNode9->data = 51;
pNode8->pNext = pNode9;
pNode9->pNext = nullptr;
}
//遍历链表内容
void show_list(Node* pHead) {
Node* tmp = pHead;
while (tmp) {
std::cout << tmp->data << " ";
tmp = tmp->pNext;
}
std::cout << std::endl;
}
// 链表反转1: 从第一个元素循环
void reverse_list1(Node* &pHead) {
if (!pHead || !pHead->pNext) {
return;
}
Node* pCurNode = pHead;
Node* pNextNode = nullptr;
Node* pPreNode = nullptr;
while (pCurNode) {
pNextNode = pCurNode->pNext;
pCurNode->pNext = pPreNode;
pPreNode = pCurNode;
pCurNode = pNextNode;
}
pHead = pPreNode;
}
// 链表反转2: 从第二个元素循环
void reverse_list2(Node** pHead) {
if (!pHead || !(*pHead)->pNext) {
return;
}
Node* pCurNode = *pHead;
Node* pNextNode = (*pHead)->pNext;
(*pHead)->pNext = nullptr;
while (pNextNode) {
Node* pTmpNode = pNextNode->pNext;
pNextNode->pNext = pCurNode;
pCurNode = pNextNode;
pNextNode = pTmpNode;
}
*pHead = pCurNode;
}
int main() {
Node* pHead = nullptr;
build_list(pHead);
show_list(pHead);
//reverse_list1(pHead);
reverse_list2(&pHead);
show_list(pHead);
return 0;
}
2.2 合并
(1)修改原始链表的合并
#include<iostream>
using namespace std;
struct Node {
int data;
Node* pNext;
};
//链表冒泡排序
void list_bubbling_sort(Node* pHead) {
if (!pHead) {
return;
}
Node* pDeal = pHead;
while (pDeal) {
Node* pBack = pDeal ->pNext;
while (pBack) {
if (pDeal->data > pBack->data) {
int iTemp = pDeal->data;
pDeal->data = pBack->data;
pBack->data = iTemp;
}
pBack = pBack->pNext;
}
pDeal = pDeal->pNext;
}
}
//构建链表
void build_list(Node*& pHead) {
pHead = new Node;
pHead->data = 90;
Node* pNode1 = new Node;
pNode1->data = 18;
pHead->pNext = pNode1;
Node* pNode2 = new Node;
pNode2->data = 3;
pNode1->pNext = pNode2;
Node* pNode3 = new Node;
pNode3->data = 56;
pNode2->pNext = pNode3;
Node* pNode4 = new Node;
pNode4->data = 32;
pNode3->pNext = pNode4;
Node* pNode5 = new Node;
pNode5->data = 45;
pNode4->pNext = pNode5;
Node* pNode6 = new Node;
pNode6->data = 23;
pNode5->pNext = pNode6;
Node* pNode7 = new Node;
pNode7->data = 21;
pNode6->pNext = pNode7;
Node* pNode8 = new Node;
pNode8->data = 9;
pNode7->pNext = pNode8;
Node* pNode9 = new Node;
pNode9->data = 51;
pNode8->pNext = pNode9;
pNode9->pNext = nullptr;
}
//遍历链表内容
void show_list(Node* pHead) {
Node* tmp = pHead;
while (tmp) {
std::cout << tmp->data << " ";
tmp = tmp->pNext;
}
std::cout << std::endl;
}
//有序链表合并成, 修改原始链表
void merge_list1(Node* pHead1, Node* pHead2, Node* &pHead) {
if (!pHead1 && !pHead2) {
return;
}
if (!pHead1) {
pHead = pHead2;
return;
}
if (!pHead2) {
pHead = pHead1;
return;
}
if (pHead1->data < pHead2->data) {
pHead = pHead1;
pHead1 = pHead1->pNext;
}
else {
pHead = pHead2;
pHead2 = pHead2->pNext;
}
Node* pCurNode = pHead;
while (pHead1 && pHead2) {
if (pHead1->data < pHead2->data) {
pCurNode->pNext = pHead1;
pHead1 = pHead1->pNext;
}
else {
pCurNode->pNext = pHead2;
pHead2 = pHead2->pNext;
}
pCurNode = pCurNode->pNext;
}
if (!pHead1) {
pCurNode->pNext = pHead2;
return;
}
if (!pHead2) {
pCurNode->pNext = pHead1;
return;
}
}
// 修改原始列表合并的测试
void merge_list_test1() {
Node* pHead1;
Node* pHead2;
//构建链表
build_list(pHead1);
build_list(pHead2);
show_list(pHead1);
show_list(pHead2);
//排序列表
list_bubbling_sort(pHead1);
list_bubbling_sort(pHead2);
show_list(pHead1);
show_list(pHead2);
//合并链表
Node* pHead;
merge_list1(pHead1, pHead2, pHead);
show_list(pHead1);
show_list(pHead2);
show_list(pHead);
}
int main() {
merge_list_test1();
return 0;
}
(2)不修改原始链表的合并
#include<iostream>
using namespace std;
struct Node {
int data;
Node* pNext;
};
//链表冒泡排序
void list_bubbling_sort(Node* pHead) {
if (!pHead) {
return;
}
Node* pDeal = pHead;
while (pDeal) {
Node* pBack = pDeal ->pNext;
while (pBack) {
if (pDeal->data > pBack->data) {
int iTemp = pDeal->data;
pDeal->data = pBack->data;
pBack->data = iTemp;
}
pBack = pBack->pNext;
}
pDeal = pDeal->pNext;
}
}
//构建链表
void build_list(Node*& pHead) {
pHead = new Node;
pHead->data = 90;
Node* pNode1 = new Node;
pNode1->data = 18;
pHead->pNext = pNode1;
Node* pNode2 = new Node;
pNode2->data = 3;
pNode1->pNext = pNode2;
Node* pNode3 = new Node;
pNode3->data = 56;
pNode2->pNext = pNode3;
Node* pNode4 = new Node;
pNode4->data = 32;
pNode3->pNext = pNode4;
Node* pNode5 = new Node;
pNode5->data = 45;
pNode4->pNext = pNode5;
Node* pNode6 = new Node;
pNode6->data = 23;
pNode5->pNext = pNode6;
Node* pNode7 = new Node;
pNode7->data = 21;
pNode6->pNext = pNode7;
Node* pNode8 = new Node;
pNode8->data = 9;
pNode7->pNext = pNode8;
Node* pNode9 = new Node;
pNode9->data = 51;
pNode8->pNext = pNode9;
pNode9->pNext = nullptr;
}
//遍历链表内容
void show_list(Node* pHead) {
Node* tmp = pHead;
while (tmp) {
std::cout << tmp->data << " ";
tmp = tmp->pNext;
}
std::cout << std::endl;
}
//有序链表合并成, 不修改原始链表
void merge_list2(Node* pHead1, Node* pHead2, Node* &pHead) {
if (!pHead1 && !pHead2) {
return;
}
pHead = new Node;
Node* pCurNode = pHead;
if (!pHead1) {
while (pHead2) {
pCurNode->data = pHead2->data;
pHead2 = pHead2->pNext;
pCurNode->pNext = new Node;
pCurNode = pCurNode->pNext;
pCurNode->pNext = nullptr;
}
return;
}
if (!pHead2) {
while (pHead1) {
pCurNode->data = pHead1->data;
pHead1 = pHead1->pNext;
pCurNode->pNext = new Node;
pCurNode = pCurNode->pNext;
pCurNode->pNext = nullptr;
}
return;
}
if (pHead1->data < pHead2->data) {
pCurNode->data = pHead1->data;
pHead1 = pHead1->pNext;
}
else {
pCurNode->data = pHead2->data;
pHead2 = pHead2->pNext;
}
while (pHead1 && pHead2) {
if (pHead1->data < pHead2->data) {
pCurNode->pNext = new Node;
pCurNode = pCurNode->pNext ;
pCurNode->data = pHead1->data;
pHead1 = pHead1->pNext;
}
else {
pCurNode->pNext = new Node;
pCurNode = pCurNode->pNext ;
pCurNode->data = pHead2->data;
pHead2 = pHead2->pNext;
}
}
if (!pHead1) {
while (pHead2) {
pCurNode->pNext = new Node;
pCurNode = pCurNode->pNext ;
pCurNode->data = pHead2->data;
pHead2 = pHead2->pNext;
}
pCurNode->pNext = nullptr;
return;
}
if (!pHead2) {
while (pHead1) {
pCurNode->pNext = new Node;
pCurNode = pCurNode->pNext ;
pCurNode->data = pHead1->data;
pHead1 = pHead1->pNext;
}
pCurNode->pNext = nullptr;
return;
}
}
// 不修改原始列表合并的测试
void merge_list_test2() {
Node* pHead1;
Node* pHead2;
//构建链表
build_list(pHead1);
build_list(pHead2);
show_list(pHead1);
show_list(pHead2);
//排序列表
list_bubbling_sort(pHead1);
list_bubbling_sort(pHead2);
show_list(pHead1);
show_list(pHead2);
//合并链表
Node* pHead;
merge_list2(pHead1, pHead2, pHead);
show_list(pHead1);
show_list(pHead2);
show_list(pHead);
}
int main() {
merge_list_test2();
return 0;
}
5.缓存
5.1 最近最少使用(LRU)
#include<iostream>
#include <list>
#include <map>
using namespace std;
// std::list存放key
// std::map 存放 key -> (vaue, key在std::list中的位置)
// 存放: key存放在list头部,map中存放key,value以及key在list中的具体位置
// 取值: key 在map中找到vaue以及keystd::list的位置,位置如果不在最前面,则删除重新插入
// 删除:从list尾部进行删除
class lru_cache
{
public:
lru_cache(size_t capacity)
: m_capacity(capacity)
{
}
~lru_cache()
{
}
size_t size() const
{
return m_map.size();
}
size_t capacity() const
{
return m_capacity;
}
bool empty() const
{
return m_map.empty();
}
bool contains(const int &key)
{
return m_map.find(key) != m_map.end();
}
// 插入新值
void insert(const int &key, const int &value)
{
std::map<int, std::pair<int, std::list<int>::iterator>>::iterator i = m_map.find(key);
if(i == m_map.end()){
if(size() >= m_capacity){
evict();
}
// 新来的数据对应key放入链表头部
m_list.push_front(key);
// map中存放key,value及其key在链表中的位置
m_map[key] = std::make_pair(value, m_list.begin());
}
}
// 获取key对应value
int get(const int &key)
{
std::map<int, std::pair<int, std::list<int>::iterator>>::iterator i = m_map.find(key);
if(i == m_map.end()){
return 0;
}
// 根据map迭代器找到key在链表中的位置
std::list<int>::iterator j = i->second.second;
// 新访问的数据必须放在最开始位置
if(j != m_list.begin()){
// 不在最开始位置将原来的进行删除,然后将其插入,插入一定是在最开始的位置
m_list.erase(j);
m_list.push_front(key);
j = m_list.begin();
const int &value = i->second.first;
m_map[key] = std::make_pair(value, j);
return value;
}
else {
return i->second.first;
}
}
void clear()
{
m_map.clear();
m_list.clear();
}
private:
void evict()
{
std::list<int>::iterator i = --m_list.end();
m_map.erase(*i);
m_list.erase(i);
}
private:
//存放key, <value, key在list中的位置>,选择map是为了方便查找,存储key在list中的位置是为了在list快速删除
std::map<int, std::pair<int, std::list<int>::iterator>> m_map;
//存放key,选择list是为了方便在一定容量内进行插入和删除
std::list<int> m_list;
size_t m_capacity;
};
int main(int argc, char *argv[])
{
lru_cache lruCache(10);
return 0;
}
6.字符串
6.1 点分ipv4地址格式化处理
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
int main() {
std::string str;
int iData = 0, iData1, iData2, iData3;
sscanf("123.12.34.56", "%d.%d.%d.%d", &iData, &iData1, &iData2, &iData3);
std::cout << iData << std::endl;
std::cout << iData1 << std::endl;
std::cout << iData2 << std::endl;
std::cout << iData3 << std::endl;
char tmpBuf[1024] = {0};
sprintf(tmpBuf, "%d.%d.%d.%d", iData, iData1, iData2, iData3);
std::cout << tmpBuf << std::endl;
return 0;
}
6.2 字符串拆分
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
std::vector<std::string> split(const char* pStr, char sepor) {
std::vector<std::string> strVec;
if (!pStr) {
return strVec;
}
int iLen = strlen(pStr);
std::string str;
for (int i = 0; i < iLen; i++) {
if (sepor == *(pStr + i)) {
if (!str.empty()) {
strVec.emplace_back(str);
str.clear();
}
}
else {
str.push_back(*(pStr + i));
}
}
}
std::vector<std::string> split(const std::string& str, char sparator) {
if (str.empty()) {
return std::vector<std::string>();
}
std::vector<std::string> strVec;
int iCurPos = 0, iLastPos = 0;
while (std::string::npos != (iCurPos = str.find(sparator, iLastPos))) {
if (iLastPos != iCurPos) {
strVec.emplace_back(str.substr(iLastPos, iCurPos - iLastPos));
}
iLastPos = ++iCurPos;
}
return strVec;
}
int main() {
std::vector<std::string> strVec = split("A10;D20;E30;W40;;;;", ';');
for (const auto & item : strVec) {
std::cout << item << std::endl;
}
return 0;
}
6.3 查找最长重复子串
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;
void findMaxRepeatSubStr(const std::string &str, std::string &strMaxSub) {
int iLen = str.size();
if (iLen <= 1) {
return;
}
std::map<std::string, int> siMap;
std::string strSub;
int iPos = -1;
// 按照个数从 1 -> iLen / 2查找子串
for (int iNum = 1; iNum <= iLen / 2; iNum++) {
for (int i = 0; i < iLen; i++) {
strSub = str.substr(i, iNum);
if (strSub.length() != iNum) {
strSub.clear();
continue;
}
if (siMap.end() == siMap.find(strSub)) {
siMap[strSub] = 1;
} else {
siMap[strSub]++;
}
}
}
//遍历查找最长重复子串
std::map<std::string, int>::iterator iter = siMap.end();
int iMax = 0;
for (auto item = siMap.begin(); item != siMap.end(); item++) {
if (item->second > 1 && item->first.length() > iMax) {
iter = item;
iMax = item->first.length();
}
}
if (iter != siMap.end()) {
strMaxSub = iter->first;
}
}
int main() {
std::string str;
findMaxRepeatSubStr("abcabcdacdacda", str);
std::cout << str << std::endl;
return 0;
}
7.IO流
7.1 字符串和文件IO流
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cstring>
#include <sstream>
#include <map>
#include <fstream>
using namespace std;
//文件输出流
void test_of() {
std::ofstream of("test.txt", std::ios::out | std::ios::app);
if (of) {
of << 123 << std::endl;
of << "hello worl" << std::endl;
}
of.close();
}
//文件输入流
void test_if() {
std::ifstream ifs("test.txt", std::ios::in);
int iData = 0;
std::string str;
// 一次读取一个单词
/*
while (!ifs.eof()) {
str.clear();
ifs >> str;
//文件最后一行是空白行
if (ifs.eof() && str.empty()) {
break;
}
std::cout << str << std::endl;
}
*/
//一次读取一行
while (std::getline(ifs, str)) {
if (str.empty()) {
continue;
}
std::cout << str << std::endl;
}
ifs.close();
}
//字符串io流
void test_sstream() {
std::stringstream istr;
istr << "hello\n" << std::endl << "qazsedc" << std::endl << "AAAAAA" << std::endl << std::endl;
std::string str;
istr >> str;
while (std::getline(istr, str)) {
if (str.empty()) {
continue;
}
std::cout << str << std::endl;
}
}
int main() {
test_of();
test_if();
return 0;
}
7.2 清空不想要的缓冲区
// C语言
#include <cstdio.h>
while (getchar() != '\n')
// C++
#include <limits>
std::cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
#include <iostream>
#include <limits>
using namespace std;
int main() {
int num = 0, id, iBoss, iIncome;
std::cin >> num;
if (num <= 0) {
return -1;
}
for (int i = 0; i < num; i++) {
std::cin >> id >> iBoss >> iIncome;
// 将丢弃输入流中的所有内容,包括换行符。
std::cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
std::cout << "=========> " << id << " " << iBoss << " " << iIncome << std::endl;
}
return 0;
}
8.VC++
8.1 Mutex和临界区
忘记释放Mutex和临界区的线程会一直运行,并不会出现死锁
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
HANDLE hMutex = NULL;
CRITICAL_SECTION g_cs;
DWORD WINAPI ThreadFun1(LPVOID lpParam)
{
while (true) {
WaitForSingleObject(hMutex, INFINITE);
cout << (int)lpParam << endl;
Sleep(1000);
ReleaseMutex(hMutex);
}
return(0);
}
DWORD WINAPI ThreadFun2(LPVOID lpParam)
{
while (true) {
WaitForSingleObject(hMutex, INFINITE);
cout << (int)lpParam << endl;
Sleep(1000);
//ReleaseMutex(hMutex);
}
return(0);
}
DWORD WINAPI ThreadFun3(LPVOID lpParam)
{
while (true) {
EnterCriticalSection(&g_cs);
cout << (int)lpParam << endl;
Sleep(1000);
LeaveCriticalSection(&g_cs);
}
return(0);
}
DWORD WINAPI ThreadFun4(LPVOID lpParam)
{
while (true) {
EnterCriticalSection(&g_cs);
cout << (int)lpParam << endl;
Sleep(1000);
//LeaveCriticalSection(&g_cs);
}
return(0);
}
void test_mutex() {
HANDLE hThread = NULL;
DWORD dwThreadId;
hMutex = CreateMutex(NULL, true, "true");
ReleaseMutex(hMutex);
hThread = CreateThread(NULL, 0, ThreadFun1, (LPVOID)1, 0, &dwThreadId);
hThread = CreateThread(NULL, 0, ThreadFun2, (LPVOID)2, 0, &dwThreadId);
getchar();
system("pause");
CloseHandle(hThread);
CloseHandle(hMutex);
}
void test_section() {
DWORD dwThreadId;
InitializeCriticalSection(&g_cs);
HANDLE hThread1 = CreateThread(NULL, 0, ThreadFun3, (LPVOID)3, 0, &dwThreadId);
HANDLE hThread2 = CreateThread(NULL, 0, ThreadFun4, (LPVOID)4, 0, &dwThreadId);
Sleep(400000);
//关闭线程句柄
CloseHandle(hThread1);
CloseHandle(hThread2);
//关闭事件对象句柄
DeleteCriticalSection(&g_cs);
}
9.字节数组与十六进制字符串转换
#include <iostream>
char lowByteToHex(int xxc)
{
xxc &= 0x0f;
if (xxc<0x0a) xxc += '0';
else xxc += 0x37;
return (char)xxc;
}
char highByteToHex(int xxc)
{
xxc &= 0xf0;
xxc = xxc >> 4;
if (xxc < 0x0a) xxc += '0';
else xxc += 0x37;
return (char)xxc;
}
// 字节数组转16进制字符串
int byteArrToHexStr(const char byteArr[], int len, char hexStr[])
{
int i;
for (i = 0; i < len; i++)
{
hexStr[2*i] = highByteToHex(byteArr[i]);
hexStr[2*i+1] = lowByteToHex(byteArr[i]);
}
return(len*2);
}
char hexToByte(const char ch1, const char ch2)
{
char ch;
if (ch1>='A') ch = (char)((ch1-0x37)<<4);
else ch = (char)((ch1-'0')<<4);
if (ch2>='A') ch |= ch2-0x37;
else ch |= ch2-'0';
return ch;
}
//16进制字符串转字节数组
int hexStrToByteArr(const char hexStr[], int len, char byteArr[])
{
int i,j;
if (len % 2 == 0)
j = len / 2;
else
j = len / 2 + 1;
for (i = 0; i < j; i++)
byteArr[i] = hexToByte(hexStr[2*i], hexStr[2*i+1]);
return(j);
}
int main(int argc, char *argv[])
{
char tmpBufHex[256] = {0};
byteArrToHexStr("012345678|*", 11, tmpBufHex);
std::cout << tmpBufHex << std::endl;
char tmpBufByteArr[256] = {0};
hexStrToByteArr(tmpBufHex, 21, tmpBufByteArr);
std::cout << tmpBufByteArr << std::endl;
return 0;
}
运行效果展示:
10.字节数组转二进制字符串
10.1QT版本
bool byteAerrayToBigEndianBinStr(const QByteArray& arr, QString &binStr) {
int iArrSize = arr.size();
if (0 == iArrSize) {
return false;
}
QByteArray tmpByteArr;
tmpByteArr.resize(iArrSize * 8);
char ch = 0;
int index = 0;
for (int i = 0; i < iArrSize; i++) {
ch = arr[i];
for (int j = 0; j < 8; j++) {
tmpByteArr[index] = (ch >> (7-j)) & 1;
tmpByteArr[index] = tmpByteArr[index] + '0';
index++;
}
}
binStr = QString(tmpByteArr);
return true;
}
10.2标准C++版本
bool byteAerrayToBigEndianBinStr(const std::vector<char>& byteArr, std::string &binStr) {
int iArrSize = byteArr.size();
if (0 == iArrSize) {
return false;
}
std::vector<char> tmpByteArr;
tmpByteArr.resize(iArrSize * 8); // tmpByteArr.reserve(iArrSize * 8); 不能使用reserve,reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size!
char ch = 0;
int index = 0;
for (int i = 0; i < iArrSize; i++) {
ch = byteArr[i];
for (int j = 0; j < 8; j++) {
tmpByteArr[index] = (ch >> (7-j)) & 1;
tmpByteArr[index] = tmpByteArr[index] + '0';
index++;
}
}
//binStr.resize(tmpByteArr.size());
//std::copy(tmpByteArr.begin(), tmpByteArr.end(), binStr.begin());
binStr = std::string(tmpByteArr.begin(), tmpByteArr.end());
return true;
}
11. 整数和字节转换
// 四字节整数获取每个字节数据,四个字节合并成一个四字节整数
int cmd = 0x12345678;
int first = (cmd >> 24) & 0xFF;
int second = (cmd >> 16) & 0xFF;
int third = (cmd >> 8) & 0xFF;
int fouth = (cmd) & 0xFF;
std::cout << first << " " <<
second << " " <<
third << " " <<
fouth << std::endl;
int result = (first << 24) & 0xFF000000;
result |= (second << 16) & 0x00FF0000;
result |= (third << 8) & 0x0000FF00;
result |= fouth & 0x000000FF;
std::cout << std::hex << result << std::endl;
运行结果如下: