面接問題その他

3861 ワード

<span style="font-family: Arial, Helvetica, sans-serif;">1,9 6 ,    2014             memcpy    : void* memcpy(void *dest , const void* src , size_t count)  dest     ,src    。   c++/c memcpy   ,   memcpy。</span>
<span style="font-family: Arial, Helvetica, sans-serif;">    :  ,      void* memcpy(void *dst, const void *src, size_t count)     </span>
{      
    //      
    assert( (dst != NULL) && (src != NULL) );      
  
    unsigned char *pdst = (unsigned char *)dst;      
    const unsigned char *psrc = (const unsigned char *)src;      
  
    //        
    assert(!(psrc<=pdst && pdst<psrc+count));      
    assert(!(pdst<=psrc && psrc<pdst+count));      
  
    while(count--)      
    {      
       *pdst = *psrc;      
        pdst++;      
        psrc++;      
    }      
    return dst;      
} 
   
2,9月9日、迅雷2014校は筆記試験のプログラミング問題を募集した.
集合AとBの要素はそれぞれヘッダノードを含まない単一チェーンテーブルで格納されることが知られており、関数difference()は集合AとBの差セットを解き、結果を集合Aの単一チェーンテーブルに保存するために使用される.例えば、集合A={5,10,20,15,25,30}であれば、集合B={5,15,35,25}となり、計算が完了するとA={10,20,30}となる.
チェーンテーブルノードの構造タイプは次のように定義されます.
struct node  
{  
    int elem;  
    node* next;  
};  
  
void difference(node** LA , node* LB)  
{  
    node *pa , *pb , *pre , *q;  
    pre = NULL;  
    pa = *LA;                              //1  
    while(pa)
    {
        pb = LB;  
        while(pb && pa->elem != pb->elem)  //2  
            pb = pb->next;  
        if(pb)                             //3  
        {  
            if(!pre)  
                *LA = pa->next;            //4  
            else  
                pre->next = pa->next;      //5  
            q = pa;  
            pa = pa->next;  
            free(q);
        }  
        else  
        {  
            pre = pa;                      //6  
            pa = pa->next;  
        }  
    }  
}  

3.9月10日、美団網2014校招研究開発筆記試験ハルビン駅1、チェーン時計が反転した.チェーンテーブル1→2→3→4→5→6,k=2のようなチェーンテーブルと数kが与えられ,反転後2→1→4→3→6→5,k=3,反転後3→2→1→6→5→4,k=4,反転後4→3→1→5→6,プログラムで実現される.
//     4   。    
void my_rotate(char *begin, char *mid, char *end)    
{       
    int n = end - begin;       
    int k = mid - begin;       
    int d = gcd(n, k);       
    int i, j;       
    for (i = 0; i < d; i ++)       
    {       
        int tmp = begin[i];       
        int last = i;       
            
        //i+k i  k   ,%n  i+k>n       。    
        for (j = (i + k) % n; j != i; j = (j + k) % n)    //  laocpp  。       
        {       
            begin[last] = begin[j];           
            last = j;       
        }           
        begin[last] = tmp;       
    }       
}     

上記の手順の解釈:2番目のforサイクルについて、jは(i+k)%nに初期化され、プログラム注釈では既に述べているように、i+kはi右シフトkの位置であり、%nはi+k>nのときに左から再開される.なぜそうするのか.簡単で、n個の数の配列はループ左シフト数にかかわらず、上記のプログラムの方法で合計n回交換する必要がある.i+k>=nのとき、i+kが表す位置は配列に存在しないので、また左から(i+k)%nは次の交換の位置です.   
char * invert(char *start, char *end)    
{       
    char tmp, *ptmp = start;        
    while (start != NULL && end != NULL && start < end)      
   {       
        tmp = *start;       
        *start = *end;          
        *end = tmp;         
         start ++;       
         end --;     
     }    
    return ptmp;    
}    
  
char *left(char *s, int pos)   //pos         ,   ,        ,pos=3。    
{    
    int len = strlen(s);    
    invert(s, s + (pos - 1));  //  ,X->X^T,  abc->cba    
    invert(s + pos, s + (len - 1)); //  ,Y->Y^T,  def->fed    
    invert(s, s + (len - 1));  //  ,    ,(X^TY^T)^T=YX,  cbafed->defabc。    
    return s;    
}