zoukankan      html  css  js  c++  java
  • 面试中经常出现的算法

    二分查找的代码.
    int bfind(int* a,int len,int val)
    {
        int m = len/2;
        int l = 0;
        int r = len;
        while(l!=m && r!= m)
        {
            if(a[m] > val)
            {
                r = m;
                m = (m+l)/2;
            }
            else if(a[m] < val)
            {
                l = m;
                m = (m+r)/2;
            }
            else
                return m;
        }
        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        {
                size_t m = i;
                for(size_t j=0;j            {
                    if(s1[m]!=s2[j])
                        break;
                    m++;
                }
                if(j==len)
                    break;
            }
            return i    }

    写出快速排序或者某种排序算法代码
    快速排序:
    int partition(int* a,int l,int r)
    {
        int i=l-1,j=r,v=a[r];
        while(1)
        {
            while(a[++i]        while(a[--j]>v) if(j<=i) break;
            if(i>=j)
                break;
            swap(a[i],a[j]);
        }
        swap(a[i],a[r]);
        return i;
    }

    void qsort(int* a,int l,int r)
    {
        if(l>=r) return;
        int i = partition(a,l,r);
        qsort(a,l,i-1);
        qsort(a,i+1,r);
    }

    冒泡排序:
    void buble(int *a,int n)
    {
        for(int i=0;i    {
            for(int j=1;j        {
                if(a[j]            {
                    int temp=a[j];
                    a[j] = a[j-1];
                    a[j-1] = temp;
                }
            }
        }
    }
    插入排序:
    void insertsort(int* a,int n)
    {
        int key;
        for(int j=1;j    {
            key = a[j];
            for(int i=j-1;i>=0&&a[i]>key;i--)
            {
                a[i+1] = a[i];
            }
            a[i+1] = key;
        }
    }

    出现次数相当频繁

    实现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    {
            char c = *p1;
            *p1++ = *p2;
            *p2-- = c;
       }
    }

    将一个单链表逆序
    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 lt;
        lt.phead = new list_node(0,0);
        lt.phead->next = new list_node(1,0);
        lt.phead->next->next = new list_node(2,0);
        lt.phead->next->next->next = new list_node(3,0);
        lt.reserve();
        list_node * p = lt.phead;
        while(p)
        {
            cout<data<        p = p->next;
        }


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

    //双向循环
    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;
    }


    将一个数字字符串转换为数字."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;
    }
    出现次数相当频繁


    .实现任意长度的整数相加或者相乘功能。
    void bigadd(char* num,char* str,int len)
    {
        for(int i=len;i>0;i--)
        {
            num[i] += str[i];
            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 );   
    }

     

     原文地址 http://hi.baidu.com/_xiao_qiang_/blog/item/d4a00930e8e6dba35fdf0e7d.html
  • 相关阅读:
    _ 下划线 Underscores __init__
    Page not found (404) 不被Django的exception中间件捕捉 中间件
    从装修儿童房时的门锁说起
    欧拉定理 费马小定理的推广
    线性运算 非线性运算
    Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
    Avoiding Full Table Scans
    批量的单向的ssh 认证
    批量的单向的ssh 认证
    Corrupted MAC on input at /usr/local/perl/lib/site_perl/5.22.1/x86_64-linux/Net/SSH/Perl/Packet.pm l
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1936373.html
Copyright © 2011-2022 走看看