适配器
取反适配器
一元取反适配器
class g5:public unary_function<int,bool>
{
public:
bool operator()(int v) const {
return v > 5;
}
};
int main()
{
vector<int> v(10);
for (int i = 0; i < 10; i++)
v[i] = i;
vector<int>::iterator it = find_if(v.begin(), v.end(),not1(g5()) );
cout << *it << endl;
return 0;
}
函数指针适配器
void func(int v,int start)
{
cout << v << endl;
}
void test03()
{
vector<int> v;
int n;
cin >> n;
for_each(v.begin(),v.end(),bind2nd(ptr_fun(func),n));
}
成员函数适配器
class person{
public:
void func();
};
vector<person> v;//假如为vector<person*> v; 就用mem_fun
for_each(v.begin(),v.end(),mem_fun_ref(&person::func);//成员函数适配器
class person:继承两个类
find_if(v.begin(),v.end(),not1(bind2nd(greater<int>,num)))
常用算法
常用遍历算法
struct person{
void operator()(int v)
{
cout << v << endl;
}
};//这样也是仿函数,struct 作用域默认为public
person p = for_each(v.begin(),v.end(),person());//返回值为一个对象,可以保存内部记录
//transform算法,将指定容器区间元素搬运到另一元素中,要提前给目标容器分配好内存
class tra{
public:
int operator()(int val){
return val;//return v + n;
}
};
vector<int> v1;
vector<int> v2(10);//也可以用reserve函数
transform(v1.begin(),v1.end(),v2.begin(),tra());//为什么用仿函数呢,因为到时候可以用适配器,增加策略
//第二种用法 将两个容器数据进行运算后搬运到第三个容器
class tra2{
public:
int operator()(int v1,int v2){
return v1 + v2;
}
}
vector<int> v3(10);
trsform(v1.begin(),v1.end(),v2.begin(),v3.begin(),tra2());
常用查找算法
//find 和 find_if 差别就是find 已经给你定义好了底层 而find_if需要自己写仿函数实现
vector<int>::iterator it = find(v.begin(),v.end(),num);//找为num的这个数
//若为自定义类型,要重载自定义类型中的 == 符号
//不能传指针,传指针只能用find_if,要用适配器
//adjacent_find 查找相邻重复元素 不用指定元素,只能返回第一个找到的 例如 1 3 4 5 5 6 6,就返回第一个5的迭代器
adjacent_find(v.begin(),v.end());
//binary_search 二分查找法,在无序序列不可用
if(binary_search(v.begin(),v.end(),elem)) //返回值为bool类型
//count统计元素出现个数
int n = count(v.begin(),v.end(),elem);
//count_if
int n = count_if(v.begin(),v.end(),bind2nd(greater<int>,elem));
常用排序算法
//merge算法 容器元素合并,并存储到另一容器中 这两个容器,必须也是有序的
vector<int> v1;
vector<int> v2;
vector<int> target;
target.resize(v1.size()+v2.size());
merge(v1.begin(),v1.end(),v2.begin(),v2.end(),ttarget.begin());
//sort
//random_shuffle算法 洗牌算法
//随机数种子
srand((unsigned int)time(NULL));
random_shuffle(v.begin(),v.end());//随机算法,打乱顺序
//reverse算法反转指定范围元素
reverse(v.begin(),v.end());
常用拷贝和替换算法
//copy算法,将一个容易指定范围的元素拷贝到另一容器中 当然要提前开辟空间
copy(v1.begin(),v1.end(),v2.begin());
//#include <iterator>
copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));//copy到流迭代器中,然后打印
//replace 替换
replace(v.begin(),v.end(),oldelem,newelem);//把旧的值替换为新的值
//replace_if
replace_if(v.begin(),v.end(),bind2nd(greater<int>(),oldelem),newelem);//把所有满足某个条件的值替换为newelem
//swap交换两个容器的元素
swap(v1,v2);
常用算数生成算法
//accmulate 计算容器元素累计合
#include <numeric>
int value = 0;//作为起始累加值
int sum = accmulate(v.begin(),v.end(),value);//总和为sum
//fill 填充容器
fill(v.begin(),v.end(),n);//n为要填充进去的值
常用集合算法
//set_intersection 求两个集合的交集,两个集合必须为有序序列
vector<int>::iterator it = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
//v1,v2为两个集合,v3为目标集合,返回值为目标容器最后一个元素的迭代器地址
//set_union 求两个集合的并集
//set_difference 求两个集合差集
贪吃蛇案例完整代码实现
#pragma once
#include <iostream>
using namespace std;
#include "wall.h"
class Food {
public:
Food(Wall& tempwall);
void setFood();
int foodX;
int foodY;
Wall &wall;
};
#include "food.h"
#include <windows.h>
void gotoxy2(HANDLE hOut2, int x, int y)//其中x,y是与正常理解相反的,注意区分
{
COORD pos;
pos.X = x; //横坐标
pos.Y = y; //纵坐标
SetConsoleCursorPosition(hOut2, pos);
}
HANDLE hOut2 = GetStdHandle(STD_OUTPUT_HANDLE);
Food::Food(Wall & tempwall):wall(tempwall)
{
}
void Food::setFood()
{
while (true) {
foodX = rand() % (Wall::ROW - 2) + 1;
foodY = rand() % (Wall::COL - 2) + 1;
if (wall.getWall(foodX, foodY) == ' '){
wall.setWall(foodX, foodY, 'o');
gotoxy2(hOut2, foodY * 2, foodX);
cout << 'o';
break;
}
}
}
#pragma once
#include <iostream>
using namespace std;
#include "wall.h"
#include "food.h"
class Snake {
public:
struct Point
{
int x;
int y;
Point *next;
};
enum {
UP = 'w',
DOWN = 's',
LEFT = 'a',
RIGHT = 'd'
};
Snake(Wall &tempwall,Food &tempfood);
void initSnake();
void delSnake();
void addPoint(int x,int y);
void delPoint();
bool move(char key);
Point *pHead;
Wall &wall;
Food &food;
bool isRool;
};
#include "snake.h"
#include <windows.h>
void gotoxy1(HANDLE hOut1, int x, int y)//其中x,y是与正常理解相反的,注意区分
{
COORD pos;
pos.X = x; //横坐标
pos.Y = y; //纵坐标
SetConsoleCursorPosition(hOut1, pos);
}
HANDLE hOut1 = GetStdHandle(STD_OUTPUT_HANDLE);
Snake::Snake(Wall & tempwall, Food &tempfood):wall(tempwall),food(tempfood)
{
pHead = NULL;
isRool = false;
}
void Snake::initSnake()
{
delSnake();
addPoint(5, 3);
addPoint(5, 4);
addPoint(5, 5);
}
void Snake::delSnake()
{
Point *pCur = pHead;
while (pHead != NULL) {
pCur = pHead->next;
delete pHead;
pHead = pCur;
}
}
void Snake::addPoint(int x, int y)
{
Point *newp = new Point;
newp->x = x;
newp->y = y;
newp->next = NULL;
if (pHead != NULL) {
wall.setWall(pHead->x, pHead->y, '*');
gotoxy1(hOut1,pHead->y * 2, pHead->x);
cout << '*';
}
newp->next = pHead;
pHead = newp;
wall.setWall(pHead->x, pHead->y, '@');
gotoxy1(hOut1, pHead->y * 2, pHead->x);
cout << '@';
}
void Snake::delPoint()
{
if (pHead == NULL || pHead->next == NULL)
return;
Point *phead = pHead;
Point *p = phead->next;
while (p->next != NULL)
{
phead = phead->next;
p = p->next;
}
wall.setWall(p->x, p->y, ' ');
gotoxy1(hOut1, p->y * 2, p->x);
cout << ' ';
delete p;
p = NULL;
phead->next = NULL;
}
bool Snake::move(char key)
{
int x = pHead->x;
int y = pHead->y;
switch (key) {
case UP:
x--;
break;
case DOWN:
x++;
break;
case LEFT:
y--;
break;
case RIGHT:
y++;
break;
default:
break;
}
Point *phead = pHead;
Point *p = phead->next;
while (p->next != NULL)
{
phead = phead->next;
p = p->next;
}//判断,如果是尾巴,就不删除
if (x == p->x && y == p->y) {
isRool = true;
}
else {
if (wall.getWall(x, y) == '#' || wall.getWall(x, y) == '*') {
addPoint(x,y);
delPoint();
//system("cls");
//wall.drawWall();
gotoxy1(hOut1, 0, 26);
cout << "GAME OVER!!" << endl;
return false;
}
}
if (wall.getWall(x, y) == 'o') {
addPoint(x, y);
food.setFood();
}
else {
addPoint(x, y);
delPoint();
if (isRool == true) {
wall.setWall(x, y, '@');
gotoxy1(hOut1, y * 2, x);
cout << '@';
}
}
return true;
}
#ifndef _WALL_HEAD
#define _WALL_HEAD
#include <iostream>
using namespace std;
class Wall {
public:
enum {
ROW = 26,
COL = 26
};//初始化墙壁
void initWall();
void drawWall();
void setWall(int x,int y,char c);//根据索引设置二维数组里面的内容
char getWall(int x,int y);//获取当前位置的符号
private:
char gameArray[ROW][COL];
};
#endif
#include "wall.h"
void Wall::initWall()
{
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
if (i == 0 || j == 0 || i == ROW - 1 || j == COL - 1)
gameArray[i][j] = '#';
else
gameArray[i][j] = ' ';
}
}
}
void Wall::drawWall()
{
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++)
cout << gameArray[i][j] << " ";
if (i == 5) cout << "小蛇名字:杨振";
if (i == 6) cout << "版本号:250 gamename:贪吃蛇";
cout << endl;
}
}
void Wall::setWall(int x, int y, char c)
{
gameArray[x][y] = c;
}
char Wall::getWall(int x, int y)
{
return gameArray[x][y];
}
#include <iostream>
#include <ctime>
#include <conio.h>
#include <windows.h>
using namespace std;
#include "wall.h"
#include "snake.h"
#include "food.h"
void gotoxy(HANDLE hOut, int x, int y)//其中x,y是与正常理解相反的,注意区分
{
COORD pos;
pos.X = x; //横坐标
pos.Y = y; //纵坐标
SetConsoleCursorPosition(hOut, pos);
}
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
int main()
{
srand((unsigned int)time(NULL));
bool isDead = false;
char preKey = NULL;
Wall wall;
wall.initWall();
wall.drawWall();//这一步特别重要
Food food(wall);
food.setFood();
Snake snake(wall,food);
snake.initSnake();
while (!isDead) {
char key = _getch();
if (key == snake.LEFT && preKey == NULL) {
continue;
}
do {
if (key == snake.DOWN || key == snake.LEFT || key == snake.RIGHT || key == snake.UP)
{
if ((key == snake.LEFT && preKey == snake.RIGHT) ||
(key == snake.RIGHT && preKey == snake.LEFT) ||
(key == snake.DOWN && preKey == snake.UP) ||
(key == snake.UP && preKey == snake.DOWN)) {
key = preKey;
}
else {
preKey = key;
}
if (snake.move(key) == true) {
//system("cls");
//wall.drawWall();
Sleep(100);
}
else {
isDead = true;
break;
}
}
else {
key = preKey;//输入其他按键,强制为上一次正确输入的案件
}
} while (!_kbhit());//当没有键盘输入,返回0
}
return 0;
}