• 有一个数组a[1000]存放01000;要求每隔二个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。


    有一个数组a[1000]存放0--1000;要求每隔二个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。
    以7个数为例:
    {0,1,2,3,4,5,6,7} 0-->1-->2(删除)-->3-->4-->5(删除)-->6-->7-->0(删除),如此循环直到最后一个数被删除。
    方法1:数组
    #include
    using namespace std;
    #define null 1000

    int main()
    {
    int arr[1000];
    for (int i=0;i<1000;++i)
    arr[i]=i;
    int j=0;
    int count=0;
    while(count<999)
    {
    while(arr[j%1000]==null)
    j=(++j)%1000;
    j=(++j)%1000;
    while(arr[j%1000]==null)
    j=(++j)%1000;
    j=(++j)%1000;
    while(arr[j%1000]==null)
    j=(++j)%1000;
    arr[j]=null;
    ++count;
    }
    while(arr[j]==null)
    j=(++j)%1000;

    cout<<J<<ENDL;
    return 0;
    }方法2:链表
    #include
    using namespace std;
    #define null 0
    struct node
    {
    int data;
    node* next;
    };
    int main()
    {
    node* head=new node;
    head->data=0;
    head->next=null;
    node* p=head;
    for(int i=1;i<1000;i++)
    {
    node* tmp=new node;
    tmp->data=i;
    tmp->next=null;
    head->next=tmp;
    head=head->next;
    }
    head->next=p;
    while(p!=p->next)
    {
    p->next->next=p->next->next->next;
    p=p->next->next;
    }
    cout<data;
    return 0;
    }
    方法3:通用算法
    #include
    #define MAXLINE 1000 //元素个数
    /*
    MAXLINE 元素个数
    a[] 元素数组
    R[] 指针场
    suffix 下标
    index 返回最后的下标序号
    values 返回最后的下标对应的值
    start 从第几个开始
    K 间隔
    */
    int find_n(int a[],int R[],int K,int& index,int& values,int s=0) {
    int suffix;
    int front_node,current_node;
    suffix=0;
    if(s==0) {
    current_node=0;
    front_node=MAXLINE-1;
    }
    else {
    current_node=s;
    front_node=s-1;
    }
    while(R[front_node]!=front_node) {
    printf("%d\n",a[current_node]);
    R[front_node]=R[current_node];
    if(K==1) {
    current_node=R[front_node];
    continue;
    }
    for(int i=0;i<K;I++){
    front_node=R[front_node];
    }
    current_node=R[front_node];
    }
    index=front_node;
    values=a[front_node];

    return 0;
    }
    int main(void) {
    int a[MAXLINE],R[MAXLINE],suffix,index,values,start,i,K;
    suffix=index=values=start=0;
    K=2;

    for(i=0;ia[i]=i;
    R[i]=i+1;
    }
    R[i-1]=0;
    find_n(a,R,K,index,values,2);
    printf("the value is %d,%d\n",index,values);
    return 0;
    }

    试题:
    void test2()
    {
    char string[10], str1[10];
    int i;
    for(i=0; i<10; i++)
    {
    str1[i] = 'a';
    }
    strcpy( string, str1 );
    }
    解答:对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10 分;
    str1不能在数组内结束:因为str1的存储为:{a,a,a,a,a,a,a,a,a,a},没有'\0'(字符串结束符),所以不能结束
    strcpy( char *s1,char *s2)他的工作原理是,扫描s2指向的内存,逐个字符付到s1所指向的内存,直到碰到'\0',因为str1结尾没有'\0',所以具有不确定性,不知道他后面还会付什么东东。
    正确应如下
    void test2()
    {
    char string[10], str1[10];
    int i;
    for(i=0; i<9; i++)
    {
    str1[i] = 'a'+i; //把abcdefghi赋值给字符数组
    }
    str[i]='\0';//加上结束符
    strcpy( string, str1 );
    }

    第二个code题是实现strcmp
    int StrCmp(const char *str1, const char *str2)
    做是做对了,没有抄搞,比较乱
    int StrCmp(const char *str1, const char *str2)
    {
    assert(str1 && srt2);
    while (*str1 && *str2 && *str1 == *str2) {
    str1++, str2++;
    }
    if (*str1 && *str2)
    return (*str1-*str2);
    elseif (*str1 && *str2==0)
    return 1;
    elseif (*str1 = = 0 && *str2)
    return -1;
    else
    return 0;
    }

    int StrCmp(const char *str1, const char *str2)
    {
    //省略判断空指针(自己保证)
    while(*str1 && *str1++ = = *str2++);
    return *str1-*str2;
    }
    第三个code题是实现子串定位
    int FindSubStr(const char *MainStr, const char *SubStr)
    做是做对了,没有抄搞,比较乱
    int MyStrstr(const char* MainStr, const char* SubStr)
    {
    const char *p;
    const char *q;
    const char * u = MainStr;

    //assert((MainStr!=NULL)&&( SubStr!=NULL));//用断言对输入进行判断
    while(*MainStr) //内部进行递增
    {
    p = MainStr;
    q = SubStr;
    while(*q && *p && *p++ == *q++);
    if(!*q )
    {
    return MainStr - u +1 ;//MainStr指向当前起始位,u指向
    }
    MainStr ++;
    }
    return -1;
    }

    分析:
    int arr[] = {6,7,8,9,10};
    int *ptr = arr;
    *(ptr++)+=123;
    printf(“ %d %d ”, *ptr, *(++ptr));
    输出:8 8
    过程:对于*(ptr++)+=123;先做加法6+123,然后++,指针指向7;对于printf(“ %d %d ”, *ptr, *(++ptr));从后往前执行,指针先++,指向8,然后输出8,紧接着再输出8

    华为全套完整试题
    高级题
    6、已知一个单向链表的头,请写出删除其某一个结点的算法,要求,先找到此结点,然后删除。
    slnodetype *Delete(slnodetype *Head,int key){}中if(Head->number==key)
    {
    Head=Pointer->next;
    free(Pointer);
    break;
    }
    Back = Pointer;
    Pointer=Pointer->next;
    if(Pointer->number==key)
    {
    Back->next=Pointer->next;
    free(Pointer);
    break;
    }
    void delete(Node* p)
    {
    if(Head = Node)

    while(p)
    }

    有一个16位的整数,每4位为一个数,写函数求他们的和。
    解释:
    整数1101010110110111
    和 1101+0101+1011+0111
    感觉应该不难,当时对题理解的不是很清楚,所以写了一个函数,也不知道对不对。
    疑问:
    既然是16位的整数,1101010110110111是2进制的,那么函数参数怎么定义呢,请大虾指教。
    答案:用十进制做参数,计算时按二进制考虑。
    /* n就是16位的数,函数返回它的四个部分之和 */
    char SumOfQuaters(unsigned short n)
    {
    char c = 0;
    int i = 4;
    do
    {
    c += n & 15;
    n = n >> 4;
    } while (--i);

    return c;
    }

    有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数.(华为)
    #include

    int main()
    {
    int a[] = {10,6,9,5,2,8,4,7,1,3};
    int len = sizeof(a) / sizeof(int);
    int temp;

    for(int i = 0; i < len; )
    {
    temp = a[a[i] - 1];
    a[a[i] - 1] = a[i];
    a[i] = temp;

    if ( a[i] == i + 1)
    i++;
    }
    for (int j = 0; j < len; j++)
    cout<<A[J]<<",";

    return 0;
    }

    (慧通)
    1 写出程序把一个链表中的接点顺序倒排
    typedef struct linknode
    {
    int data;
    struct linknode *next;
    }node;
    //将一个链表逆置
    node *reverse(node *head)
    {
    node *p,*q,*r;
    p=head;
    q=p->next;
    while(q!=NULL)
    {
    r=q->next;
    q->next=p;
    p=q;
    q=r;
    }

    head->next=NULL;
    head=p;
    return head;
    }
    2 写出程序删除链表中的所有接点
    void del_all(node *head)
    {
    node *p;
    while(head!=NULL)
    {
    p=head->next;
    free(head);
    head=p;
    }
    cout<<"释放空间成功!"<<ENDL;
    }
    3两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串
    void insert(char *s, char *t, int i)
    {
    char *q = t;
    char *p =s;
    if(q == NULL)return;
    while(*p!='\0')
    {
    p++;
    }
    while(*q!=0)
    {
    *p=*q;
    p++;
    q++;
    }
    *p = '\0';
    }


    分析下面的代码:
    char *a = "hello";
    char *b = "hello";
    if(a= =b)
    printf("YES");
    else
    printf("NO");
    这个简单的面试题目,我选输出 no(对比的应该是指针地址吧),可在VC是YES 在C是NO
    lz的呢,是一个常量字符串。位于静态存储区,它在程序生命期内恒定不变。如果编译器优化的话,会有可能a和b同时指向同一个hello的。则地址相同。如果编译器没有优化,那么就是两个不同的地址,则不同
    写一个函数,功能:完成内存之间的拷贝
    memcpy source code:
    270 void* memcpy( void *dst, const void *src, unsigned int len )
    271 {
    272 register char *d;
    273 register char *s;
    27
    275 if (len == 0)
    276 return dst;
    277
    278 if (is_overlap(dst, src, len, len))
    279 complain3("memcpy", dst, src, len);
    280
    281 if ( dst > src ) {
    282 d = (char *)dst + len - 1;
    283 s = (char *)src + len - 1;
    284 while ( len >= 4 ) {
    285 *d-- = *s--;
    286 *d-- = *s--;
    287 *d-- = *s--;
    288 *d-- = *s--;
    289 len -= 4;
    290 }
    291 while ( len-- ) {
    292 *d-- = *s--;
    293 }
    294 } else if ( dst < src ) {
    295 d = (char *)dst;
    296 s = (char *)src;
    297 while ( len >= 4 ) {
    298 *d++ = *s++;
    299 *d++ = *s++;
    300 *d++ = *s++;
    301 *d++ = *s++;
    302 len -= 4;
    303 }
    304 while ( len-- ) {
    305 *d++ = *s++;
    306 }
    307 }
    308 return dst;
    309 }
    公司考试这种题目主要考你编写的代码是否考虑到各种情况,是否安全(不会溢出)
    各种情况包括:
    1、参数是指针,检查指针是否有效
    2、检查复制的源目标和目的地是否为同一个,若为同一个,则直接跳出
    3、读写权限检查
    4、安全检查,是否会溢出
    memcpy拷贝一块内存,内存的大小你告诉它
    strcpy是字符串拷贝,遇到'\0'结束

    /* memcpy ─── 拷贝不重叠的内存块 */
    void memcpy(void* pvTo, void* pvFrom, size_t size)
    {
    void* pbTo = (byte*)pvTo;
    void* pbFrom = (byte*)pvFrom;
    ASSERT(pvTo != NULL && pvFrom != NULL); //检查输入指针的有效性
    ASSERT(pbTo>=pbFrom+size || pbFrom>=pbTo+size);//检查两个指针指向的内存是否重叠
    while(size-->0)
    *pbTo++ == *pbFrom++;
    return(pvTo);

  • 相关阅读:
    什么是内存泄漏?
    将博客搬至CSDN
    jQuery基础事件处理
    vue的特殊指令 v-if v-once v-bind v-for v-on v-model
    svg 直线水平渐变为什么没有效果,必须得是一条倾斜的不水平的直线才有渐变效果呢??
    jQuery基础
    Html 对象的常用事件列举
    javascript应该嵌入到html中的什么位置
    javascript document.createElement() document.createTextNode() appendChild()
    html canvas
  • 原文地址:https://www.cnblogs.com/superstar/p/1096492.html
Copyright © 2020-2023  润新知