1、字符串处理函数
strlen(s):返回s的长度,不包括字符串结束符null;
int strlen(const char *str) { assert(str!=NULL); int len=0; while((*str++)!='') len++; return len; }
sizeof运算符:单目运算符,并不是函数,以字节形式给出了其操作数的存储大小,操作数可以是一个表达式或括在括号内的类型名,操作数的存储大小由操作数的类型决定。需牢记sizeof的计算发生在编译时刻,所以它可以被当作常量表达式使用,且会忽略其括号内的各种运算,如“ sizeof(a++); ”中的++不执行。
//一般的,在32位编译环境中: sizeof(int):4 sizeof(short):2 sizeof(long):4 sizeof(float):4 sizeof(double):8 sizeof(char):1 sizeof(p):4 (p为指针)
char ch3[]="Daniel"; sizeof(ch3)=sizeof("Daniel")=7 strlen(ch3)=6 sizeof("")=2 //可见sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示,故将内容为''的数组元素计算在内,而strlen()计算字符数组的字符数,以''为结束标志,且不将''计算在字符数内。
strcat(dest, src):把src所指字符串添加到dest结尾处(覆盖dest结尾处的‘’)并添加‘’。
strcpy(dest, src):把从src地址开始且含null结束符的字符串复制到以dest开始的地址空间。
//strcat(dest,src)把src所指字符串添加到dest结尾处(覆盖dest结尾处的'')并添加'' char *strcat(char * strDest, const char *strSrc) { char *res=strDest; assert((strDest!=NULL)&&(strSrc!=NULL)); while(*strDest)strDest++; while(*strDest=*strSrc) { strDest++; strSrc++; } return res; } //strcpy(dest,src)把从src地址开始且含有null结束符的字符串复制到以dest开始的地址空间 char *strcpy(char *strDest, const char *strSrc) { char *res=strDest; assert((strDest!=NULL)&&(strSrc!=NULL)); while((*strDest=*strSrc)!='') { strDest++; strSrc++; } return res; }
memcpy:从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中,函数返回指向dest的指针。
void *memcpy(void *dest, const void *src, size_t n);
memset:将S中前n个字节用ch替换并返回s,作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
void *memset(void *s, int ch, size_t n);
strcpy和memcpy的区别:
1)复制的内容不同:strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。memcpy对于需要复制的内容没有限制,因此用途更广。
2)复制的方法不同:strcpy不需要指定长度,它遇到被复制字符的串结束符''时才结束,所以容易溢出。memcpy则是根据第三个参数决定复制的长度。
3)用途不同:通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。
字符串转换为数字:atoi
enum Status{kValid=0, KInvalid}; int g_nStatus=kValid; int StrToInt(const char *str) { g_nStatus=KInvalid; long long num=0; if((str!=NULL)&&(*str!='')) { bool minus=false; if(*str=='+')str++; else if(*str=='-') { minus=true; str++; } if(*str!='') { num=StrToIntCore(str, minus); } } return (int)num; } long long StrToIntCore(const char * digit, bool minus) { long long num=0; while(*digit!='') { if(*digit>='0'&&*digit<=9) { int flag=minus?-1:1; num=10*num+flag*(*digit-'0'); if(((!minus)&&num>0x7fffffff)||(minus&&(num<(signed int)0x80000000))) { num=0; break; } digit++; } else { num=0; break; } } if (*digit=='') { g_nStatus=kValid; } return num; }
2 设计模式-单例模式
//一般单例模式双重锁形式(java): public class Singleton{ private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if (instance==null){ synchronized(Singleton.class){ if (instance==null){ instance=new Singleton(); } } } return instance; } }
1)用两个栈实现一个队列。
请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。
解题思路:
插入操作在stack1中进行,删除操作在stack2中进行,如果stack2为空,则将stack1中的所有元素转移到stack2中。
#include<iostream> #include<stdlib.h> #include<stack> using namespace std; template <typename T>class CQueue { public: CQueue(void); ~CQueue(void); void appendtail(const T& node); T deleteHead(); private: stack<T> stack1; stack<T> stack2; }; //构造函数 template <typename T> CQueue<T>::CQueue(void) { } //析构函数 template <typename T> CQueue<T>::~CQueue(void) { } //插入元素 template <typename T> void CQueue<T>::appendtail(const T& node) { stack1.push(node); } //删除元素并返回 template <typename T> T CQueue<T>::deleteHead() { if(stack2.size()<=0) { while(stack1.size()>0) { stack2.push(stack1.top()); stack1.pop(); } } if(stack2.size()==0) throw new exception("队列为空"); T head=stack2.top(); stack2.pop(); return head; } void main() { CQueue<int> queue; queue.appendtail(1); queue.appendtail(2); queue.appendtail(3); queue.appendtail(4); int len=4; while(len>0) { cout<<queue.deleteHead()<<endl; --len; } system("pause"); }
2)使用两个队列实现一个栈
参考文献:
http://hi.baidu.com/ozwarld/blog/item/ec9b52d4d48ce1dc50da4b0f.html
解法:
- 有两个队列q1和q2,先往q1内插入a,b,c,这做的都是栈的push操作。
- 现在要做pop操作,即要得到c,这时可以将q1中的a,b两个元素全部dequeue并存入q2中,这时q2中元素为a,b,对q1再做一次dequeue操作即可得到c。
- 如果继续做push操作,比如插入d,f,则把d,f插入到q2中,
- 此时若要做pop操作,则做步骤2
- 以此类推,就实现了用两个队列来实现一个栈的目的。
注意在此过程中,新push进来的元素总是插入到非空队列中,空队列则用来保存pop操作之后的那些元素,那么此时空队列不为空了,原来的非空队列变为空了,总是这样循环。
对于push和pop操作,其时间为O(n).
#include<iostream> #include<stdlib.h> #include<stack> #include<queue> using namespace std; template <typename T>class CStack { public: CStack(void){}; ~CStack(void){}; void push(const T& node); T pop(); private: queue<T> queue1; queue<T> queue2; }; //插入元素 template <typename T> void CStack<T>::push(const T& element) { if(queue1.size()>0)//如果queue1不为空则往queue1中插入元素 queue1.push(element); else if(queue2.size()>0)//如果queue2不为空则往queue2中插入元素 queue2.push(element); else//如果两个队列都为空,则往queue1中插入元素 queue1.push(element); } //删除元素 template <typename T> T CStack<T>::pop() { if(queue1.size()==0)//如果queue1为空 { while(queue2.size()>1)//保证queue2中有一个元素,将其余元素保存到queue1中 { queue1.push(queue2.front()); queue2.pop(); } T& data=queue2.front(); queue2.pop(); return data; } else//如果queue2为空 { while(queue1.size()>1)//保证queue2中有一个元素,将其余元素保存到queue1中 { queue2.push(queue1.front()); queue1.pop(); } T& data=queue1.front(); queue1.pop(); return data; } } void main() { CStack<int> stack; stack.push(1); stack.push(2); stack.push(3); stack.push(4); int len=4; while(len>0) { cout<<stack.pop()<<" "; --len; } system("pause"); }
//用两个栈实现队列的功能 //假设有两个栈s1与s2,则s1保存刚刚入队的元素,若需出队且s2为空,则将s1所有元素压入s2(此时s2中元素顺序为元素入队顺序),然后取出s2栈顶即可,若s2非空(此时s2中元素为s1之前压入,其栈顶就是最早入队的元素),则直接取出s2的栈顶。 template<class T> class MyQueue { stack<T> s1,s2; public: MyQueue(){} int size() { return s1.size()+s2.size(); } bool empty() { if(size()==0)return true; else return false; } void push(T value) { s1.push(value); } T front() { if(!s2.empty()) { return s2.top(); } else { while(!s1.empty()) { s2.push(s1.top()); s1.pop(); } return s2.top(); } } void pop() { if(!s2.empty()) { s2.pop(); } else { while(!s1.empty()) { s2.push(s1.top()); s1.pop(); } s2.pop(); } } };
4常考排序算法
//直接插入排序 void InsertSort(int A[], int n) { int i,j; int temp; for (i=0;i<n-1;i++) { temp=A[i+1]; j=i; while (j>-1&&temp<A[j]) { A[j+1]=A[j]; j--; } A[j+1]=temp; } } //冒泡排序 void BubbleSort(int A[],int n) { int i, j, flag=1; int temp; for (i=1;i<n&&flag;i++) { flag=0; for (j=0;j<n-i;j++) { if(A[j+1]<A[j]) { flag=1; temp=A[j+1]; A[j+1]=A[j]; A[j]=temp; } } } }
//快速排序 void QuickSort(int A[], int left, int right) { int i=left, j=right; int temp=A[left]; while(i<j) { while(i<j&&temp<=A[j])j--; if(i<j)A[i++]=A[j]; while(i<j&&A[i]<temp)i++; if(i<j)A[j--]=A[i]; } A[i]=temp; if(left<i)QuickSort(A,left,i-1); if(j<right)QuickSort(A,j+1,right); } //快速排序(划分) int Partition(int A[], int n, int start, int end) { if(A==NULL||n<=0||start<0||end>=n)return -1; int index=RandomInRange(start, end); swap(&A[index],&A[end]); int small=start-1; for (index=start; index<end; ++index) { if(A[index]<A[end]) { small++; if(index!=small) { swap(&A[small],&A[index]); } } } small++; swap(&A[small],&A[end]); return small; } void QuickSort(int A[], int n, int left, int right) { if(left==right)return; int index=Partition(A, n, left, right); if(index>left) QuickSort(A,n,left,index-1); if(index<right) QuickSort(A,n,index+1,right); } void getLeastKnum(int A[], int n, int B[], int k) { if(A==NULL||n<=0||B==NULL||k<=0||n<k)return; int start=0; int end=n-1; int index=Partition(A,n,start,end); while(index!=k-1) { if(index>k-1) index=Partition(A,n,start,index-1); else index=Partition(A,n,index+1,end); } for (int i=0;i<k;i++) B[i]=A[i]; }
/* 1、(无重复)Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its index, otherwise return -1. You may assume no duplicate exists in the array. */ class Solution { public: int search(int A[], int n, int target) { if(A==NULL||n==0)return -1; int left=0,right=n-1; int mid; while(left<=right) { mid=left+(right-left)/2; if(A[mid]==target)return mid; /* if(A[mid]==A[left]&&A[mid]==A[right]) { left++; right--; } else*/ if(A[mid]>=A[left]) { if(A[mid]<target)left=mid+1; else { if(A[left]<=target)right=mid-1; else left=mid+1; } } else { if(A[mid]>target)right=mid-1; else { if(A[right]>=target)left=mid+1; else right=mid-1; } } } return -1; } };
/* 2(有重复)Search in Rotated Sorted Array II Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array. */ class Solution { public: bool search(int A[], int n, int target) { if(A==NULL||n==0)return false; int left=0,right=n-1; int mid; while(left<=right) { mid=left+(right-left)/2; if(A[mid]==target)return true; if(A[mid]==A[left]&&A[mid]==A[right]) { left++; right--; } else if(A[mid]>=A[left]) { if(A[mid]<target)left=mid+1; else { if(A[left]<=target)right=mid-1; else left=mid+1; } } else { if(A[mid]>target)right=mid-1; else { if(A[right]>=target)left=mid+1; else right=mid-1; } } } return false; } };
……