C/C++ 经典算法实例

二分查找的代码

int bfind(int* a,int len, int val)
{
    int le = 0,re = len - 1,m;
    while (le<=re)
    {
        m = (le+re)/2;
        if(a[m] == val)
            return m;
        if(a[m]>val)
            re = m - 1;
        else
            le = m + 1;
    }
    
    return -1; //
}

 

 

写出在母串中查找子串出现次数

int count1(char* str,char* s)
{
    char* s1;
    char* s2;
    int count = 0;
    while(*str!='\0')
    {
        s1 = str;
        s2 = s;
        while(*s2 == *s1&&(*s2!='\0')&&(*s1!='\0'))
        {
            s2++;
            s1++;
        }
        if(*s2 == '\0')
            count++;
        str++;
    }
    return count;
}

 




查找第一个匹配子串位置,如果返回的是s1长度len1表示没有找到 

size_t find(char* s1,char* s2)
    {
        size_t i=0;
        size_t len1 = strlen(s1);
        size_t len2 = strlen(s2);
        if(len1-len2<0) return len1;
        for(;i<len1-len2;i++)
        {
            size_t m = i;
            for(size_t j=0;j<len2;j++)
            {
                if(s1[m]!=s2[j])
                    break;
                m++;
            }
            if(j==len)
                break;
        }
        return i<len1-len2?i:len1;
    }

 

实现strcpy函数

char *strcpy(char *destination, const char *source) 
{ 
    assert(destination!=NULL&&source!=NULL);
    char* target = destinaton;
    while(*destinaton++=*source++); 
    return target ; 
} 


实现strcmp函数 

int strcmp11(char* l,char* r) 
{ 
    assert(l!=0&&r!=0); 
    while(*l == *r &&*l != '\0') l++,r++; 
    if(*l > *r) 
        return 1; 
    else if(*l == *r) 
        return 0; 
    return -1; 
} 

 

实现字符串翻转 

void reserve(char* str) 
{ 
    assert(str != NULL); 
    char * p1 = str; 
    char * p2 = str-1; 
    while(*++p2);        //一般要求不能使用strlen 
    p2 -= 1; 
    while(p1<p2)  { 
        char c = *p1; 
        *p1++ = *p2; 
        *p2-- = c; 
  } 
} 

 

将一个数字字符串转换为数字."1234" -->1234 

int atoii(char* s) 
{ 
    assert(s!=NULL); 
    int num = 0; 
    int temp; 
    while(*s>='0' && *s<='9') 
    { 
        num *= 10; 
        num += *s-'0'; 
        s++; 
    } 
    return num; 
} 

 


 


将一个单链表逆序 
struct list_node 

    list_node(int a,list_node* b):data(a),next(b) //这个为了测试方便 
    {} 
    int data; 
    list_node* next; 
}; 

void reserve(list_node* phead) 

        list_node* p = phead->next; 
        if(p == NULL || p->next == NULL) return; //只有头节点或一个节点 
        list_node* p1=p->next; 
        p->next=NULL; 
        while(p1!=NULL) 
        { 
            p = p1->next; 
            p1->next = phead->next; 
            phead->next = p1; 
            p1 = p; 
        } 



循环链表的节点对换和删除。 

//双向循环 
list_node* earse(list_node* node) 

    // if(node == rear) return node->next;    //对于头节点可判断也可不判断。最好加上 
    list_node* next = node->next; 
    next->prev = node->prev; 
    node->prev->next = next; 
    delete node; 
    retrun next; 

//单项循环 
list_node* earse(list_node* node) 

    // if(node == rear) return node->next;    //对于头节点可判断也可不判断。最好加上 
    list_node* p = rear; 
    while(p->next != node) p=p->next; 
    p->next = node->next; 
    delete node; 
    retrun p->next; 






.实现任意长度的整数相加或者相乘功能。 
void bigadd(char* num,char* str,int len) 

    for(int i=len;i>0;i--) 
    { 
        num += str; 
        int j = i; 
        while(num[j]>=10) 
        { 
            num[j--] -= 10; 
            num[j] += 1; 
        } 
    } 



.写函数完成内存的拷贝 
void* memcpy( void *dst, const void *src, unsigned int len ) 

    register char *d; 
    register char *s; 
    if (len == 0) 
        return dst; 
    if ( dst > src )  //考虑覆盖情况 
    { 
        d = (char *)dst + len - 1; 
        s = (char *)src + len - 1; 
        while ( len >= 4 )  //循环展开,提高执行效率 
        { 
            *d-- = *s--; 
            *d-- = *s--; 
            *d-- = *s--; 
            *d-- = *s--; 
            len -= 4; 
        } 
        while ( len-- ) 
        { 
            *d-- = *s--; 
        } 
    } 
    else if ( dst < src ) 
    { 
        d = (char *)dst; 
        s = (char *)src; 
        while ( len >= 4 ) 
        { 
            *d++ = *s++; 
            *d++ = *s++; 
            *d++ = *s++; 
            *d++ = *s++; 
            len -= 4; 
        } 
        while ( len-- ) 
        { 
            *d++ = *s++; 
        } 
    } 
    return dst; 

出现次数相当频繁 

编写类String的构造函数、析构函数和赋值函数,已知类String的原型为: 

class String 
{    
public:    
String(const char *str = NULL); // 普通构造函数  
String(const String &other); // 拷贝构造函数 
~ String(void); // 析构函数 
String & operate =(const String &other); // 赋值函数    
private:    
char *m_data; // 用于保存字符串    
}; 

解答: 
//普通构造函数 
String::String(const char *str) 

      if(str==NULL) 
      { 
              m_data = new char[1]; // 得分点:对空字符串自动申请存放结束标志'\0'的空 
                                   //加分点:对m_data加NULL 判断 
              *m_data = '\0'; 
      }  
      else 
      { 
        int length = strlen(str); 
        m_data = new char[length+1]; // 若能加 NULL 判断则更好 
        strcpy(m_data, str); 
      } 

// String的析构函数 
String::~String(void) 

      delete [] m_data; // 或delete m_data; 

//拷贝构造函数 
String::String(const String &other)    // 得分点:输入参数为const型 
{    
      int length = strlen(other.m_data); 
      m_data = new char[length+1];     //加分点:对m_data加NULL 判断 
      strcpy(m_data, other.m_data);  


//赋值函数 
String & String::operate =(const String &other) // 得分点:输入参数为const型 
{    
      if(this == &other)                  //得分点:检查自赋值 
              return *this; 
      delete [] m_data;              //得分点:释放原有的内存资源 
      int length = strlen( other.m_data );    
      m_data = new char[length+1];  //加分点:对m_data加NULL 判断 
      strcpy( m_data, other.m_data ); 
      return *this;            //得分点:返回本对象的引用 

剖析: 
能够准确无误地编写出String类的构造函数、拷贝构造函数、赋值函数和析构函数的面试者至少已经具备了C++基本功的60%以上! 
在这个类中包括了指针类成员变量m_data,当类中包括指针类成员变量时,一定要重载其拷贝构造函数、赋值函数和析构函数,这既是对C++程序员的基本要求,也是《Effective C++》中特别强调的条款。 

实现strcpy 

char * strcpy( char *strDest, const char *strSrc ) 

assert( (strDest != NULL) && (strSrc != NULL) ); 
char *address = strDest; 
while( (*strDest++ = * strSrc++) != ‘\0’ ); 

return address; 


编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh” 
函数头是这样的: 

//pStr是指向以'\0'结尾的字符串的指针 
//steps是要求移动的n 
void LoopMove ( char * pStr, int steps ) 

//请填充... 


解答: 
正确解答1: 
void LoopMove ( char *pStr, int steps ) 

    int n = strlen( pStr ) - steps; 
    char tmp[MAX_LEN];  
    strcpy ( tmp, pStr + n ); 
    strcpy ( tmp + steps, pStr);  
    *( tmp + strlen ( pStr ) ) = '\0'; 
    strcpy( pStr, tmp ); 


正确解答2: 
void LoopMove ( char *pStr, int steps ) 

    int n = strlen( pStr ) - steps; 
    char tmp[MAX_LEN];  
    memcpy( tmp, pStr + n, steps ); 
    memcpy(pStr + steps, pStr, n );    
    memcpy(pStr, tmp, steps );  
}

posted @ 2014-03-18 13:47  ↙公子ゞ小白  阅读(459)  评论(0)    收藏  举报