面试题目积累

一、判断字符串a中是否包含字符串b(或者字符串a中包含字符串b的字母个数)

1。使用最笨的方法,依次扫描

//时间复杂度为O(lenLong*lenShort)
int isContain(char* longString,char* shortString){
    int lenLong=strlen(longString);
    int lenShort=strlen(shortString);
    if(lenLong<lenShort){
        return 0;
    }
    int j;
    for(int i=0;i<lenShort;i++){
        for(j=0;j<lenLong;j++){
        if(longString[j]==shortString[i]){

            break;
        }
        }
        if(j==lenLong){
            cout<<"false"<<endl;
            return 0;
        }
    }
    cout<<"true"<<endl;
    return 1;
}
笨方法(循环扫描)

2,排序之后再扫描(其中采用快速排序的复杂度为O(mlogm+nlogn)+o(m+n)),采用计数排序的复杂度为O(m+n)\

//方法二,先对两个字符串中的字母进行排序,然后对两个字符串进行轮循
//两个字符串排序,复杂度为(mlogm+nlogn),之后扫描需要o(m+n),因此一共的复杂度为o(mlogm)+o(nlogn)+o(m+n)

///首先,实现对于字符的快速排序算法
int partition(char* str,int low,int high){
    int i=low;
    int j=high;
    int pivot=str[i];
    while(i<j){
        while(i<j&&str[j]>=pivot){
            j--;
        }
        if(i<j){
            str[i]=str[j];
            i++;
        }
        while(i<j&&str[i]<=pivot){
            i++;
        }
        if(i<j){
            str[j]=str[i];
            j--;
        }

    }
    str[i]=pivot;
    return i;

}

void quickSort(char *arr,int start,int end){
int i;
if(start<end){
    i=partition(arr,start,end);
    quickSort(arr,start,i-1);
    quickSort(arr,i+1,end);
    

}
}
///比较排序之后的两个字符串,进行线性扫描,时间复杂度为O(m+n)
int isContainByMethod2(char* strLong,char* strShort){
    int nLong=strlen(strLong);
    int nShort=strlen(strShort);
///如果有重复的字母,排序是什么一种情况    
    int i,j;
    for(i=0;i<=nLong-nShort;i++){
        if(strLong[i]==strShort[0]){
            for(j=0;j<=nShort-1;j++){
            if(strLong[i+j]!=strShort[j]){
                break;
            }
            }    
            if(j==nShort){
            cout<<"true"<<endl;
            return 1;
            }
        }

    }
    cout<<"flase"<<endl;
    return 0;
}


/******************方法三,同方法二,只不过排序采用的是线性排序法,这里采用计数排序的方法,排序O(n+m),线性扫描o(m+n);一共o(m+n)+o(m+n)=o(m+n)********/
void countSort(char* str){
    int help[26]={0};
    int len=strlen(str);
    char* help_str=new char[len];
    int i,n,pos;
    for(i=0;i<len;i++){
        n=str[i]-'a';
        help[n]++;
    }
    for(i=1;i<26;i++){
        help[i]+=help[i-1];
    }

    //将每个元素放在合适的位置
    for(i=len;i>=0;i--){
        n=str[i]-'a';
        pos=help[n]-1;
        help_str[pos]=str[i];
        //这个是考虑原来数组可能有相同元素
        help[n]--;
    }
    for(i=0;i<len;i++){
        str[i]=help_str[i];
    }
    delete[] help_str;
}
排序之后进行比较

 3,采用hash的方法(如果引入大素数,倒确实是一种有趣的思路,其中牵涉到大数除法,这里暂略)

void isContain(string str_long,string str_short){
    int hash[26]={0};
    int len_short=str_short.length();
    int len_long=str_long.length();
    for(int i=0;i<len_short;i++){
        int index=str_short[i]-'a';
        hash[index]=1;
    }
    for(int i=0;i<len_long;i++){
        int index=str_long[i]-'a';
        if(hash[index]==1){
            hash[index]=0;    
        }
    }
    int i=0;
    for(i=0;i<26;i++){
        if(hash[i]==1){
        break;
        }
    }
    if(i==26){
        cout<<"true"<<endl;
    }else{
        cout<<"false"<<endl;
    }
}
isContainSubStringByHash

 4,采用hash结合bitmap的方法

采用位的思想来构建辅助数组,可以大大降低控件复杂度,这中思想在解决内存有限的去重、查找、排序问题中很常见


void isContainByHashAndBitmap(string str_long,string str_short){
    int len_short=str_short.length();
    int len_long=str_long.length();
    //char 在内存中占据一个字节的存储空间
    //这里需要借助4个字节,不过这里不再借助char[4]数组了,而是采用一个int类型
    //char *hash=new char[4];
    int dictionary=0;
    for(int i=0;i<len_long;i++){
    dictionary|=getBit(str_long[i]);
    }
    int i;
    for(i=0;i<len_short;i++){
        if(dictionary!=(dictionary|getBit(str_short[i]))){
        break;
        }
    }
    if(i==len_short){
        cout<<"true"<<endl;
    }else{
        cout<<"false"<<endl;
    }

        
}
isContainByHashAndBitmap

5,判断两个字符串是否匹配,采用hash的方法

//判断字符串是否匹配,即两个字符串含有的字符个数相同,只是顺序不同
//这里对于字符串包含重复字符的情况也考虑在内了
bool is_match(const char* strOne,const char* strTwo){
    int lenOfOne=strlen(strOne);
    int lenOfTwo=strlen(strTwo);
    if(lenOfOne!=lenOfTwo){
        return false;
    }

    int hash[26]={0};

    for(int i=0;i<lenOfOne;i++){
        int index=strOne[i]-'a';
        hash[index]++;
    }

    for(int i=0;i<lenOfTwo;i++){
        int index=strTwo[i]-'a';
        if(hash[index]!=0){
        hash[index]--;
        }else{
            return false;
        }
        
    }
    return true;
    }
isMatchString

 6,查找一个字符串中子字符串的位置

#include<iostream>
#include<cstring>
using namespace std;

int main(){
    string str_long="abcdef";
    string str_short="cd";
    int findsubstring(string,string);
    int result=findsubstring(str_long,str_short);
    cout<<result<<endl;
    return 0;
}
//查找子字符串的位置,还可以考虑排序之后再查找,或者通过KMP算法,其复杂度为O(m+n)
int findsubstring(string str_long,string str_short){
int len_long=str_long.length();
int len_short=str_short.length();
for(int i=0;i<len_long-len_short;i++){
    if(str_long[i]==str_short[0]){
    int j;
    for( j=0;j<len_short;j++){
        if(str_long[i+j]!=str_short[j]){
            break;
        }    
    }
    if(j==len_short){
        cout<<"true"<<endl;
        return i;
    }
    }
}
    cout<<"false"<<endl;
    return 0;

}
findThePlaceOfSubstrin

 7,找出一个字符串中第一次只出现一次的字符

同样利用hash的方法,

#include<iostream>
#include<cstring>
using namespace std;

int main(){
    string str="eeooidjia";
    char find_first_unique_char(string);
    cout<<find_first_unique_char(str)<<endl;
    return 0;

}

char find_first_unique_char(string str){

    int hash[26]={0};
    int len=str.length();
    for(int i=0;i<len;i++){
        int index=str[i]-'a';
        hash[index]++;
    }
    for(int i=0;i<len;i++){
        int index=str[i]-'a';
        if(hash[index]==1){
            return str[i];
        }
    }
    return '/0';


}
find_first_unique_char

 8,将字符串转换为对应的数字输出,如“-12635”转换为-12635输出

(1) char转换为int的方法 -'0'

(2) '+'、'-'的符号考虑

(3) 大型数字溢出的考虑

#include<iostream>
#include<cstring>
#include<assert.h>
using namespace std;
//实现功能,将字符串转换为对应的数字,如“123”输出数字123
//需要注意的问题
//1,如果使用的指针,需要判断指针是否为空
//2,如果输入的字符串中包含有不是数字的字符,那么碰到这些非法字符的是偶,给出出错信息,判断数字是否在‘0’到‘9’之间
//3,数字可能还包含“+”,“-”号,利用一个符号位来记录该信息
//4,如果输入的是字符串形式的数字,可能存在溢出的可能,判断溢出的标志是在处理符号之前判断是否>0
int main(){
    string str="-23876";
    int str_2_int(string);
    cout<<str_2_int(str)<<endl;
    return 0;
}

int str_2_int(string str){
    assert(str.length()>0);
    int pos=0;
    int sys=1;
    if(str[pos]=='+'){
        sys=1;
        pos++;
    }else if(str[pos]=='-'){
        sys=-1;
        pos++;
    }
    int num=0;
    for(pos;pos<str.length();pos++){
        assert(str[pos]>='0');
        assert(str[pos]<='9');
        num=num*10+(str[pos]-'0');
        //处理溢出
        assert(num>=0);
    }
    num*=sys;
    return num;

}
str2int

9,字符串的复制操作,主要看考虑是否周全

#include<iostream>
#include<cstring>
#include<assert.h>
using namespace std;
//实现功能,将字符串转换为对应的数字,如“123”输出数字123
//需要注意的问题
//1,如果使用的指针,需要判断指针是否为空
//2,如果输入的字符串中包含有不是数字的字符,那么碰到这些非法字符的是偶,给出出错信息,判断数字是否在‘0’到‘9’之间
//3,数字可能还包含“+”,“-”号,利用一个符号位来记录该信息
//4,如果输入的是字符串形式的数字,可能存在溢出的可能,判断溢出的标志是在处理符号之前判断是否>0
int main(){
    string str="-23876";
    int str_2_int(string);
    cout<<str_2_int(str)<<endl;
    return 0;
}

int str_2_int(string str){
    assert(str.length()>0);
    int pos=0;
    int sys=1;
    if(str[pos]=='+'){
        sys=1;
        pos++;
    }else if(str[pos]=='-'){
        sys=-1;
        pos++;
    }
    int num=0;
    for(pos;pos<str.length();pos++){
        assert(str[pos]>='0');
        assert(str[pos]<='9');
        num=num*10+(str[pos]-'0');
        //处理溢出
        assert(num>=0);
    }
    num*=sys;
    return num;

}
字符串复制

 10,找出N(可以是个海量数据)个数中最小的K个数

思路:取出N个数中开始的k个数字构成一个初始的最大堆

遍历k到N中间的数字,和heap[0]比较,如果比heap[0]小,那么就替换heap[0],重新调整这个最大堆

在文档上还有快速排序达到O(n)复杂度的讨论,没怎么看明白,有时间再研究吧

#include<iostream>
#include<cstring>
using namespace std;

void swap(int* a,int* b){
    if(*a!=*b){
        *a=*a^*b;
        *b=*a^*b;
        *a=*a^*b;
    }
}

int leftChildPos(int pos){
    return (pos<<1)+1;//注意位移的优先级小于+,因此这里的括号一定不能省
}

int rightChildPos(int pos){
    return (pos+1)<<1;
}

int parent(int pos){
    return (pos-1)>>1;
}

bool isLeaf(int pos,int MAXLEN){
return pos>=(MAXLEN>>1)&&pos<MAXLEN;
}
void adjustHeap(int array[],int i,int len){
    int largeIndex=i;
    int left=leftChildPos(i);
    int right=rightChildPos(i);
    if(left<len&&array[largeIndex]<array[left]){
        largeIndex=left;
    }
    if(right<len&&array[largeIndex]<array[right]){
        largeIndex=right;
    }
    if(largeIndex!=i){
        swap(array[i],array[largeIndex]);
        adjustHeap(array,largeIndex,len);
    }
}
void buildHeap(int array[],int len){
if(array==NULL){return;}
int i;
for(i=len/2-1;i>=0;i--){
    adjustHeap(array,i,len);
}
}

int main(){
    int MAXLEN=10000;
    int data[10000]={0};
    int i=0;
    for(i=0;i<MAXLEN;i++){
    data[i]=MAXLEN-i;
    }
    int k=10;
    int heap[10]={0};
    for(int i=0;i<k;i++){
        heap[i]=data[i];
    }
    cout<<"排序之前的数组为:"<<endl;
    for(int i=0;i<10;i++){
    cout<<heap[i]<<" ";
    }
    cout<<endl;
    buildHeap(heap,k);
    cout<<"堆初始化之后的数组:"<<endl;
    for(int i=0;i<10;i++){
    cout<<heap[i]<<" ";
    }
    cout<<endl;
    int newData=-1;
    for(int i=10;i<MAXLEN;i++){
        newData=data[i];
        if(newData<heap[0]){
            heap[0]=newData;
            adjustHeap(heap,0,k);
        }
    }
cout<<"建立起来的最大堆为:"<<endl;
    for(int i=0;i<k;i++){
        cout<<heap[i]<<"  ";
    }
    cout<<endl;
//备注:建立起来最大堆,得到了最小的k个数,如果想要顺序排列的话,采用堆排序即可
    return 0;
}
findSmallKNum

 11.Top K问题

问题10的对立面,在实际中非常有用,即寻找最大的k个数字的问题,可以采用的算法有,这在自己的论文个性化搜索中可以体现,

比如,统计搜索引擎中的热门查询词汇

(这一点可以运用到论文的个性化搜索模块,如何将大众总体的热门搜索和用户的搜索历史融合起来,提供个性化服务,这一点值得考虑,也可以作为自己对后台的贡献部分)

所谓hashTable,就是把关键码值(key value)直接进行访问的方法,把关键码值映射到表中一个位置的方法叫做散列,存放记录的数组就叫做散列表。

哈希表hashtable(key,value) 的做法其实很简单,就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。
    而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就可以充分利用到数组的定位性能进行数据定位(文章第二、三部分,会针对Hash表详细阐述)。在下面从数量庞大的字符串数组中,判断某个特定的字符串是否存在的问题中,会用到这一点

因此对于这个问题:

第一步:query统计

维护一个key为query字符串,value为该字符串出现次数的hashtable(利用java里面内置的hashtable数据结构的话,相当于字符串映射为地址码的这一步,有系统帮助完成了)

第二步:top10问题解决

维护一个大小为10的最小堆,和解决找出最小的k个值的思路是一样的。

 12,和上面一道题目的关系是同样涉及了hashtable的概念,判断一个字符串时候存在于一个很大的字符串数组中

#include<iostream>

using namespace std;

//问题描述,有一个庞大的字符串数组,给一个单独的字符串,让你从这个字符串数组中判断是否有这个字符串并找到它

//思路:第一步:通过某种算法,将以个字符串“压缩”成一个整数,当然,无论如何,一个32位的整数是无法对应回一个字符串的(,这就是one-way hash算法的思想,这也说明funf的加密方法是不可逆的?),不过在程序中,两个字符串计算出hash值相等的可能性非常小
//第二步:通常的想法会是,逐个比较字符串的hash数值,但这种解决方案远远不够,要想得到最快的算法,就不能进行逐个的比较,通常是构造一个哈希表来解决问题,哈西表的大小根据程序进行定义,例如1024,每一个hash值通过取模运算对应到数组中的一个位置,这样,只要比较这个字符串的的哈希值对应的位置有没有占用,就可以得到最后的结果,这样事件复杂度就是O(1)<不过,最初大数组生成hash,确定对应位置是否占用,不是依旧需要遍历一次么?>
//可能的问题是“两个字符串在哈希表中对应的位置相同怎么办”,解决方法很多,一种方法就是“链表”
//但是一个更绝的方法是,其基本原理是,在哈希表中不是用一个哈希值而是用三个哈希值来校验字符串,一个用于哈西表的下标,另外两个用来验证
//总上,算法的流程为:
//1,计算出字符串的三个哈希值
//2,察看哈希表中的这个位置
//3,哈希表中该位置是否为空,如果为空,那么该字符串不存在,返回-1
//4,如果存在,那么检查其他两个哈希值是否也匹配,如果匹配,表示找到了该字符串,返回该hash值
//5,移到下一个位置,如果已经移动到了表的末尾,就反转到表的开头继续查询
//6,看看是不是回到原来位置,如果是,就返回没有找到
//7,回到3


//下面的代码仅是测试:准备hash表,并将一个字符串映射为一个数值  
 #include <stdio.h>  
    #include <ctype.h>     //多谢citylove指正。  
    //crytTable[]里面保存的是HashString函数里面将会用到的一些数据,在prepareCryptTable  
    //函数里面初始化  
    unsigned long cryptTable[0x500];  
      
    //以下的函数生成一个长度为0x500(合10进制数:1280)的cryptTable[0x500]  
    void prepareCryptTable()  
    {   
        unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i;  
      
        for( index1 = 0; index1 < 0x100; index1++ )  
        {   
            for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 )  
            {   
                unsigned long temp1, temp2;  
      
                seed = (seed * 125 + 3) % 0x2AAAAB;  
                temp1 = (seed & 0xFFFF) << 0x10;  
      
                seed = (seed * 125 + 3) % 0x2AAAAB;  
                temp2 = (seed & 0xFFFF);  
      
                cryptTable[index2] = ( temp1 | temp2 );   
           }   
       }   
    }  
      
    //以下函数计算lpszFileName 字符串的hash值,其中dwHashType 为hash的类型,  
    //在下面GetHashTablePos函数里面调用本函数,其可以取的值为0、1、2;该函数  
    //返回lpszFileName 字符串的hash值;  
    unsigned long HashString( char *lpszFileName, unsigned long dwHashType )  
    {   
        unsigned char *key  = (unsigned char *)lpszFileName;  
    unsigned long seed1 = 0x7FED7FED;  
    unsigned long seed2 = 0xEEEEEEEE;  
        int ch;  
      
        while( *key != 0 )  
        {   
            ch = toupper(*key++);  
      
            seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);  
            seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;   
        }  
        return seed1;   
    }  

      
    //在main中测试argv[1]的三个hash值:  
    //./hash  "arr/units.dat"  
    //./hash  "unit/neutral/acritter.grp"  
    int main( int argc, char **argv )  
    {  
        unsigned long ulHashValue;  
        int i = 0;  
      
        if ( argc != 2 )  
        {  
            printf("please input two arguments/n");  
            return -1;  
        }  
      
         /*初始化数组:crytTable[0x500]*/  
         prepareCryptTable();  
      
         /*打印数组crytTable[0x500]里面的值*/  
         for ( ; i < 0x500; i++ )  
         {  
             if ( i % 10 == 0 )  
             {  
                 printf("\n");  
             }  
      
             printf("%-12X", cryptTable[i] );  
         }  
      
         ulHashValue = HashString( argv[1], 0 );  
         printf("\n----%X ----\n", ulHashValue );  
      
         ulHashValue = HashString( argv[1], 1 );  
         printf("----%X ----\n", ulHashValue );  
      
         ulHashValue = HashString( argv[1], 2 );  
         printf("----%X ----\n", ulHashValue );  
      
         return 0;  
    }  

 //如果要完整实现上面的代码:
typedef struct
{
    int nHashA;
    int nHashB;
    char bExists;
   ......
} SOMESTRUCTRUE;


int GetHashTablePos( har *lpszString, SOMESTRUCTURE *lpTable )
//lpszString要在Hash表中查找的字符串,lpTable为存储字符串Hash值的Hash表。
{
    int nHash = HashString(lpszString);  //调用上述函数二,返回要查找字符串lpszString的Hash值。
    int nHashPos = nHash % nTableSize;
 
    if ( lpTable[nHashPos].bExists  &&  !strcmp( lpTable[nHashPos].pString, lpszString ) )
    {  //如果找到的Hash值在表中存在,且要查找的字符串与表中对应位置的字符串相同,
        return nHashPos;    //则返回上述调用函数二后,找到的Hash值
    }
    else
    {
        return -1; 
    }
}


 
findSpeficString

 13,libFunction

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//copy the first n char to a destStr
char *strncpy(char* strDes,const char *strSrc,unsigned int count){
    assert(strDes!=NULL&&strSrc!=NULL);
    char *address=strDes;
    while(count--&&*strSrc!='\0'){
        *strDes++=*strSrc++;
    }
    *strDes='\0';
    return address;
}

int main(){
char* strSrc="dsdfjeoi";
char* strDes=(char*)malloc(sizeof(char)*2);
strncpy(strDes,strSrc,10);
printf("%s\n",strSrc);
printf("%s\n",strDes);
printf("%d\n",sizeof(strDes));
free(strDes);
return 0;
}
strncopy
int strcmp(const char* str1,const char* str2){
    assert(str1!=NULL&&str2!=NULL);
    while(*str1&&*str2&&*str1++==*str2++);
    return(*str1-*str2);

    //while(*str1&&*str2){
    //str1++;
    //str2++;
    //}
    //return(*str1-*str2);
}
strcmp
char* strcat(char* strDes,const char* strSrc){
    assert(strDes!=NULL&&strSrc!=NULL);
    char *address=strDes;
    while(*strDes){strDes++;};
    while(*strSrc){*strDes++=*strSrc++;};
    *strDes='\0';
    return address;
}
strCat

 

//从一个长字符串中需找子字符串,如果存在,返回子字符串第一次出现的位置
//const 只能赋值给const变量
//const变量可以通过强制类型转换为对应的非const变量
 char *strstr(const char* str_long,const char* str_short){
    assert(str_long!=NULL&&str_short!=NULL);
    const    char* s;
    const char* t;
    const char* str;
    for(s=str_long;*s!='\0';s++){
        for(str=s,t=str_short;*t!='\0'&&*str==*t;t++,str++){
        }

        if(*t=='\0'){
            return (char*)s;
        }
    }
    return NULL;

}
strstr(findSubStr)
//依次检验字符串s1中的字符,当该字符在字符串s2中也包含的时候,就停止检验
char* strpbrk(const char* str1,const char* str2){
        const char* s;
        const char* t;
        for(s=str1;*s!='\0';s++){
                for(t=str2;*t!='\0';t++){
                        if(*s==*t){
                        return (char*)s;
                        }   
                }   
        }   
        return NULL;
}
strpcpy

 

//依次检验字符串s1中的字符,当该字符在字符串s2中也包含的时候,就停止检验
char* strpbrk(const char* str1,const char* str2){
        const char* s;
        const char* t;
        for(s=str1;*s!='\0';s++){
                for(t=str2;*t!='\0';t++){
                        if(*s==*t){
                        return (char*)s;
                        }   
                }   
        }   
        return NULL;
}
strpbrk
//顺序在字符串s1中寻找与s2中字符的第一个相同字符,返回这个字符在s1中第一次出现的
位置
int strcspn(const char* str1,const char* str2){
        assert(str1!=NULL&&str2!=NULL);
        const char* s;
        const char* t;
        for(s=str1;*s!='\0';s++){
                for(t=str2;*t!='\0';t++){
                        if(*s==*t){
                                return s-str1;
                        }   
                }   
        }   
        return -1; 
}
strcspn
//依次检验字符串s1中的字符,当该字符在字符串s2中也包含的时候,就停止检验
char* strpbrk(const char* str1,const char* str2){
        const char* s;
        const char* t;
        for(s=str1;*s!='\0';s++){
                for(t=str2;*t!='\0';t++){
                        if(*s==*t){
                        return (char*)s;
                        }   
                }   
        }   
        return NULL;
}
strspn
//查找一个字符c在字符串str中末次出现的位置,也就是从str的右侧开始找,字符c首次出
现的位置,并且返回从字符串的这个位置起,一直到字符串结束的所有字符,如果没有找到
指定的字符,那么返回NULL
char* strrchar(const char* str,char c){
        const char* s;
        for(s=str;*s!='\0';s++){
        }
        for(--s;*s!=c;s--){
                if(s==str){return NULL;}

        }
        return (char*)s;
}
strrchar
//将字符串中所有字符的顺序颠倒过来,这里进行的是原地修改
char* strrev( char *str){
        assert(str!=NULL);
        char* s=str;
        char* t;
        while(*s!='\0'){s++;}
//      printf("%c\n",*(--s));
        char c;
        //奇怪,为什么t!=s就不行呢?
        for(t=str,--s;t<s;t++,s--){
                c=*s;
                *s=*t;
                *t=c;
        }   
        return str;
}
strrev
//将一个字符串中前count个字符都设置为指定字符c
char* strnset(char* str,char c,unsigned int count){
        assert(str!=NULL);
        char* s;
        for(s=str;count>0&&*str!='\0';count--,s++){
                *s=c;
        }
        return str;
}
strnset
//拷贝src所指的内存内容的前n个字节到dest所指向的内存地址,同strcpy不同的地方在于
memcpy用来复制完整的n个字节,不会因为碰到‘\0’而结束
//const 修饰指针的几种情形,A:const在前面,const char*p;那么*p即p的内容是const,p指针本身可以改变。const char * const p;指针p和内容*p都不可以改变。B:const在后面,char const *p;*p即p的内容是const,指针p可以改变,char* const p,那么指针p>是const,*p即p的内容可以改变;char const * const p;p指针和p的内容都不可以改变。
规律是,以*进行分界,如果const在左侧,那么*p即p的内容可以改变,而指针不变。如果const在右侧,那么指针不可改变,但是指针指向的内容可以改变

void* memcpy(void* dest,const void* src,unsigned int n){
        void* address=dest;
        while(n--){
        *(char*)dest=*(char*)src;
        dest=(char*)dest+1;
        src=(char*)src+1;
        }   
        return address;
}
memcpy

(上个例子中提高了const指针的一些用法)

 

字符串中字符的大小写转换

//将字符串中的小写字母转换为大写形式,其他的字符不变
char* strupr(char* str){
        assert(str!=NULL);
        char* tmp=str;
        for(tmp=str;*tmp!='\0';tmp++){
                if(*tmp>'a'&&*tmp<'z'){
                        *tmp=*tmp+'A'-'a';
                }   
        }   
        return str;
}
//将字符串中的大写字母转换为小写形式,其他的字符保持不变
char* strlwr(char* str){
        assert(str!=NULL);
        char * tmp;
        for(tmp=str;*tmp!='\0';tmp++){
                if(*tmp>'A'&&*tmp<'Z'){
                        *tmp=*tmp+'a'-'A';
                }   
        }   
        return str;
}
字符串大小写转换

 

 

14,二分查找法的实现

(每一次都是利用middle处的数值和待比较的数字进行比较)

//问题描述
//输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字,>要求时间复杂度为O(n);例如,输入数字1、2、4、7、11、15和数字15.那么输出4、11

//在解决这个问题之前,首先实现一下二分查找方法
//n为数组长度,v为要寻找的数字,二分查找的前提是数组为有序数组
int binary_search(int array[],int n,int v){
        int left=0;
        int right=n-1;
        int middle;
        while(left<=right){
                middle=left+(right-left)/2;
                if(array[middle]<v){
                        left=middle+1;
                }           
                else if(array[middle]>v){
                        right=middle-1;
                } else{     
                        return middle;
                }           
        }           
        return -1;
}
binary_search

 

 

 

 

posted @ 2013-11-18 21:01  bobo的学习笔记  阅读(350)  评论(0编辑  收藏  举报