MacOS下可以通过终端输入ssh username@your.server.url ,然后根据提示输入相应的密码即可实现远程ssh登录,通过exit命令可以退出连接。
windows可以使用Bitvise SSH Client 进行ssh登录。(目前使用的是Bitvise SSH Client 6.31)
MacOS下可以通过终端输入ssh username@your.server.url ,然后根据提示输入相应的密码即可实现远程ssh登录,通过exit命令可以退出连接。
windows可以使用Bitvise SSH Client 进行ssh登录。(目前使用的是Bitvise SSH Client 6.31)
题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
题解:
使用一个小根堆和一个元素出现次数数组来维护这个栈;
每次push一个元素,该元素出现次数+1,并把该元素压进小根堆
每次pop一个元素,该元素出现次数-1,如果小根堆的栈顶元素出现次数为0,则一直pop,直到栈顶元素出现次数不为0
AC代码:
/* 题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。 题解: 使用一个小根堆和一个元素出现次数数组来维护这个栈; 每次push一个元素,该元素出现次数+1,并把该元素压进小根堆 每次pop一个元素,该元素出现次数-1,如果小根堆的栈顶元素出现次数为0,则一直pop,直到栈顶元素出现次数不为0 */ class Solution { public: stack<int> s; map<int, int> m; static struct cmp { bool operator()(const int&a, const int &b) { return a>b; } }; priority_queue<int, vector<int>, cmp> pq; void push(int value) { s.push(value); pq.push(value); m[value]++; } void pop() { m[s.top()]--; s.pop(); while (m[pq.top()] == 0) pq.pop(); } int top() { return s.top(); } int min() { return pq.top(); } };
方法一:
计算整个程序运行的时间。可以使用time命令,譬如我要运行的文件是app,正常情况下是在终端里面输入./app ,我们可以使用time ./app运行程序,在程序结束后,会看到一些时间参数,其中Real是程序实力占用时间user是程序用时间包括一些输出信息等,sys是系统使用时间,比如库的调用。
方法二:
测量程序中部分代码运行时间。
首先包含头文件:
#include <sys/time.h>
然后新建时间结构:
struct timeval StartTime; struct timeval EndTime; double TimeUse=0; gettimeofday(&StartTime, NULL); //要测量的程序代码 gettimeofday(&EndTime, NULL); TimeUse = 1000000*(EndTime.tv_sec-StartTime.tv_sec)+EndTime.tv_usec-StartTime.tv_usec; TimeUse/=1000; cout<<“总花费时间为:”<<TimeUse<<“ms”<<endl; cout<<“总花费时间为:”<<TimeUse/1000<<“s”<<endl; cout<<“总花费时间为:”<<(int)(TimeUse/1000)/60<<“分”<<((int)(TimeUse/1000))%60<<“秒”<<endl;
1.需要包含头文件netinet/in.h,IPPROTO_TCP、IPPROTO_IPV6等定义在这个头文件中。
2.exit定义在stdlib.h中。
3.需要定义sock_str_flag、sock_str_int、sock_str_linger和sock_str_timeval。
4.理论上每个sock_opts都应该用ifdef进行判断,但是考虑到centos本身就没有sctp相关选项,所以直接屏蔽。
checkopts.cpp,github网址:https://github.com/siukwan/unix/tree/master/7thChapterSocketOpt
代码如下:
/* * sock_opts定义应该每一个都有if else的判断 * 实际情况是没有sctp的选项,于是直接屏蔽 * */ #include<stdio.h> #include<iostream> #include<netinet/tcp.h> #include<netinet/in.h> #include<sys/socket.h> #include <stdarg.h> #include<syslog.h> #include<errno.h> #include<string.h> #include<stdlib.h> #include<unistd.h> using namespace std; #define MAXLINE 1024 int daemon_proc; void err_ret(const char *fmt,...); void err_quit(const char *fmt,...); union val{ int i_val; long l_val; linger linger_val; timeval timeval_val; }sock_val; static char *sock_str_flag(val *,int); static char *sock_str_int(val*,int); static char *sock_str_linger(val* ,int); static char *sock_str_timeval(val*,int); struct opts{ const char *opt_str; int opt_level; int opt_name; char *(*opt_val_str)(val *,int); }sock_opts[]={ {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, sock_str_flag }, {"SO_DEBUG", SOL_SOCKET, SO_DEBUG, sock_str_flag }, {"SO_DONTROUTE", SOL_SOCKET, SO_DONTROUTE, sock_str_flag }, {"SO_ERROR", SOL_SOCKET, SO_ERROR, sock_str_int }, {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, sock_str_flag }, {"SO_LINGER", SOL_SOCKET, SO_LINGER, sock_str_linger }, {"SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE, sock_str_flag }, {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, sock_str_int }, {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, sock_str_int }, {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, sock_str_int }, {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, sock_str_int }, {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, sock_str_timeval }, {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, sock_str_timeval }, {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, sock_str_flag }, #ifdef SO_REUSEPORT {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, sock_str_flag }, #else {"SO_REUSEPORT", 0, 0, NULL }, #endif {"SO_TYPE", SOL_SOCKET, SO_TYPE, sock_str_int }, #ifdef SO_USELOOPBACK {"SO_USELOOPBACK", SOL_SOCKET, SO_USELOOPBACK, sock_str_flag }, #else {"SO_USELOOPBACK", 0, 0, NULL }, #endif #ifdef IP_TOS {"IP_TOS", IPPROTO_IP, IP_TOS, sock_str_int }, #else {"IP_TOS", 0, 0, NULL }, #endif #ifdef IP_TTL {"IP_TTL", IPPROTO_IP, IP_TTL, sock_str_int }, #else {"IP_TTL", 0, 0, NULL }, #endif #ifdef IPV6_DONTFRAG {"IPV6_DONTFRAG", IPPROTO_IPV6, IPV6_DONTFRAG, sock_str_flag }, #else {"IPV6_DONTFRAG", 0, 0, NULL }, #endif {"IPV6_UNICAST_HOPS", IPPROTO_IPV6, IPV6_UNICAST_HOPS, sock_str_int }, {"IPV6_V6ONLY", IPPROTO_IPV6, IPV6_V6ONLY, sock_str_flag }, {"TCP_MAXSEG", IPPROTO_TCP, TCP_MAXSEG, sock_str_int }, {"TCP_NODELAY", IPPROTO_SCTP, TCP_NODELAY, sock_str_flag }, // {"SCTP_AUTOCLOSE", IPPROTO_TCP, SCTP_AUTOCLOSE, sock_str_int }, // {"SCTP_MAXBURST", IPPROTO_SCTP, SCTP_MAXBURST, sock_str_int }, // {"SCTP_MAXSEG", IPPROTO_SCTP, SCTP_MAXSEG, sock_str_int }, // {"SCTP_NODELAY", IPPROTO_SCTP, SCTP_NODELAY, sock_str_flag }, {NULL, 0, 0, NULL }, }; int main(int argc,char **argv) { int fd; socklen_t len; opts *ptr; for(ptr=sock_opts;ptr->opt_str !=NULL;ptr++) { printf("%s:",ptr->opt_str); if(ptr->opt_val_str == NULL) printf("(undefined)\n"); else { switch(ptr->opt_level) { case SOL_SOCKET: case IPPROTO_IP: case IPPROTO_TCP: fd = socket(AF_INET,SOCK_STREAM,0); break; default: err_quit("Can't create fd for level %d\n",ptr->opt_level); } len = sizeof(val); if(getsockopt(fd,ptr->opt_level,ptr->opt_name,&sock_val,&len) == -1) err_ret("getsockopt error"); else printf("default = %s\n",(*ptr->opt_val_str)(&sock_val,len)); close(fd); } } } //记录日志 void err_doit(int errnoflag, int level ,const char *fmt, va_list ap) { int errno_save,n; char buf[MAXLINE+1]; errno_save = errno; #ifdef HAVE_VSNPRINTF vsnprintf(buf,MAXLINE, fmt , ap); #else vsprintf(buf,fmt,ap); #endif n=strlen(buf); if(errnoflag) snprintf(buf+n,MAXLINE-n,": %s",strerror(errno_save)); strcat(buf,"\n"); if(daemon_proc) { syslog(level,buf); } else { fflush(stdout); fputs(buf,stderr); fflush(stderr); } } //错误退出,和上面一样 void err_quit(const char *fmt,...) { va_list ap; va_start(ap,fmt); err_doit(0,LOG_ERR, fmt,ap); va_end(ap); exit(1); } void err_ret(const char *fmt,...) { va_list ap; va_start(ap,fmt); err_doit(1,LOG_INFO,fmt,ap); va_end(ap); return ; } static char strres[128]; static char * sock_str_flag(union val *ptr, int len) { /* *INDENT-OFF* */ if (len != sizeof(int)) snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len); else snprintf(strres, sizeof(strres), "%s", (ptr->i_val == 0) ? "off" : "on"); return(strres); /* *INDENT-ON* */ } /* end checkopts3 */ static char * sock_str_int(union val *ptr, int len) { if (len != sizeof(int)) snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len); else snprintf(strres, sizeof(strres), "%d", ptr->i_val); return(strres); } static char * sock_str_linger(union val *ptr, int len) { struct linger *lptr = &ptr->linger_val; if (len != sizeof(struct linger)) snprintf(strres, sizeof(strres), "size (%d) not sizeof(struct linger)", len); else snprintf(strres, sizeof(strres), "l_onoff = %d, l_linger = %d", lptr->l_onoff, lptr->l_linger); return(strres); } static char * sock_str_timeval(union val *ptr, int len) { struct timeval *tvptr = &ptr->timeval_val; if (len != sizeof(struct timeval)) snprintf(strres, sizeof(strres), "size (%d) not sizeof(struct timeval)", len); else snprintf(strres, sizeof(strres), "%d sec, %d usec", tvptr->tv_sec, tvptr->tv_usec); return(strres); }
AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树。AVL树得名于它的发明者 G.M. Adelson-Velsky 和 E.M. Landis,他们在 1962 年的论文 “An algorithm for the organization of information” 中发表了它。
其中AVL树主要的操作包括:左旋、右旋、两种情况的双旋转。下面先给出旋转的示意图:
单旋:
两种情况的双旋:
下面,根据上述的旋转示意图编写递归的代码:
struct AvlNode{ int val, height; AvlNode*l, *r; AvlNode() :val(-1), height(-1), l(NULL), r(NULL){}; AvlNode(int x) :val(x), height(0), l(NULL), r(NULL){}; }; static int Height(AvlNode* T) {//求高度 if (T == NULL) return -1; else return T->height; } static AvlNode* SingleRotateLeft(AvlNode* k2) {//左旋,把树顺时针旋转 AvlNode*k1 = k2->l; k2->l = k1->r; k1->r = k2; //注意更新高度 k2->height = max(Height(k2->l), Height(k2->r)) + 1; k1->height = max(Height(k1->l), k2->height) + 1; return k1; } static AvlNode* SingleRotateRight(AvlNode* k1) {//右旋,把树逆时针旋转 AvlNode*k2 = k1->r; k1->r = k2->l; k2->l = k1; //注意更新高度 k1->height = max(Height(k1->l), Height(k1->r)) + 1; k2->height = max(Height(k2->r), k1->height) + 1; return k2; } static AvlNode* DoubleRotateLeft(AvlNode* k3) {//先把k2(k3->l)逆时针旋转,再把k3顺时针旋转 k3->l = SingleRotateRight(k3->l); return SingleRotateLeft(k3); } static AvlNode* DoubleRotateRight(AvlNode* k1) {//先把k2(k1->r)逆时针旋转,再把k1顺时针旋转 k1->r = SingleRotateLeft(k1->r); return SingleRotateRight(k1); } static AvlNode* Insert(int x, AvlNode*T) { if (T == NULL)//如果节点为空,则新建一个节点 T = new AvlNode(x); else if (x < T->val) {//x小于T的值,则插入左边 T->l = Insert(x, T->l); if (Height(T->l) - Height(T->r) == 2) {//插入后,左边比右边高2,则需要调整 if (x < T->l->val)//如果插入的值是在左子树的左边,则左旋即可 T = SingleRotateLeft(T); else//如果插入的值是在左子树的右边,那么需要双旋转 T = DoubleRotateLeft(T); } } else if (x > T->val) {//如果插入的值大于T的值,则插入T的右子树中 T->r = Insert(x, T->r); if (Height(T->r) - Height(T->l) == 2) {//高度差为2,需要调整 if (x>T->r->val)//如果在右子树的右边,单选即可 T = SingleRotateRight(T); else//在右子树的左边,需要双旋 T = DoubleRotateRight(T); } } //注意更新高度 T->height = max(Height(T->l), Height(T->r)) + 1; return T; }
这些天在弄OpenCV,用来把两张640*480的图片拼在一起,拼成1280*480,然后发现调用下面这个函数的时候内存一直在增大,貌似有些变量无法释放内存.
void Show2Image(cv::Mat cvImg1, cv::Mat cvImg2) { beginTime =clock(); std::cout<<“图片合并开始时间:”<<beginTime<<std::endl; IplImage* image1=&cvImg1.operator IplImage(); IplImage* image2=&cvImg2.operator IplImage(); IplImage* image3 = cvCreateImage( cvSize(image1->width+image2->width,MAX(image1->height,image2->height)),IPL_DEPTH_8U,3); CvRect rect=cvRect(0,0,image1->width,image1->height); cvSetImageROI(image3,rect); cvCopy(image1,image3); cvResetImageROI(image3); rect=cvRect(image1->width,0,image2->width,image2->height); cvSetImageROI(image3,rect); cvCopy(image2,image3); cvResetImageROI(image3); cvShowImage(“Kinect Follow & Xtion ObstacleAvoide”,image3); //cvReleaseImage(&image3); endTime =clock(); std::cout<<“结束时间:”<<endTime<<std::endl <<“图片合并花费时间:”<<endTime-beginTime<<std::endl<<std::endl; }
经过排查,发现是
IplImage* image3 = cvCreateImage( cvSize(image1->width+image2->width,MAX(image1->height,image2->height)),IPL_DEPTH_8U,3);
这句代码导致内存增大.
然后发现cvCreateImage需要和cvReleaseImage配合用,譬如上述代码,需要用cvReleaseImage(&image3);来释放image3的内存,而image1和image2不是用cvCreateImage创建的,所以不用使用cvReleaseImage来释放,假如你使用了,反而会报错.
解决方案:
在VS2010经历一些更新,或者是在装完VS2010后再安装了更高级的版本,例如VS2012,VS2013等,会出现
LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
的错误!
解决方案为将 项目|项目属性|配置属性|清单工具|输入和输出|嵌入清单 “是”改为“否”即可,但是没新建一个项目都要这样设置一次。
在建立VS2010 Win32 Project项目时,按照上面解决方案依然发生了“error LNK1123”错误,经过上网查资料,解决方案为:
第一步:与上相同。
第二步:将 项目|项目属性|配置属性|连接器|清单文件|嵌入清单 “是”改为“否”。
第三步:一般计算机经过上两步设置就能解决问题了,但是如果还有问题,那就按一下方法解决:
找到Microsoft Visual Studio 10.0\VC\bin ,把cvtres.exe删除,然后找到新版本的VC\bin里面的cvtres.exe拷贝过来.
例如,我的VS2010 bin路径是在 C:\Program Files\Microsoft Visual Studio 10.0\VC\bin
VS2012 bin路径是在D:\Program Files\Microsoft Visual Studio 12.0\VC\bin
把10.0\bin里面的cvtres.exe删除,把12.0\bin里面的cvtres.exe复制到10.0\bin里面
然后运行程序就没问题了!
意外的是,治本的办法是第三步,删除旧版本的cvtres.exe后,就不需要每次都设置配置了。