• C语言面试题3


    编程题

    1、读文件file1.txt的内容(例如):

    123456

    输出到file2.txt:

    563412

    #include <stdio.h>
    #include <stdlib.h> 
    
    int main(void)
    {
        int MAX = 10;
        int *a = (int *)malloc(MAX * sizeof(int));
        int *b; 
    
        FILE *fp1;
        FILE *fp2;
        fp1 = fopen("a.txt","r");
        if(fp1 == NULL)
        {
            printf("error1");
            exit(-1);
        }
    
        fp2 = fopen("b.txt","w");
        if(fp2 == NULL)
        {
            printf("error2");
            exit(-1);
        } 
    
        int i = 0;
        int j = 0; 
        while(fscanf(fp1,"%d",&a[i]) != EOF)
        {
            i++;j++;
            if(i >= MAX)
            {
               MAX = 2 * MAX;
               b = (int*)realloc(a,MAX * sizeof(int));
               if(b == NULL)
               {
                  printf("error3");
             exit(-1);
           }
          a = b;
         }
       }
    
    for(;--j >= 0;)
       fprintf(fp2,"%d
    ",a[j]);
    
    fclose(fp1);
    fclose(fp2);
    return 0;
    }                                                      

    对1的另一种做法:

     1 #include <stdio.h>
     2 void test(FILE *fread, FILE *fwrite)
     3 {
     4         char buf[1024] = {0};
     5         if (!fgets(buf, sizeof(buf), fread))
     6                 return;
     7         test( fread, fwrite );
     8         fputs(buf, fwrite);
     9 }
    10 int main(int argc, char *argv[])
    11 {
    12         FILE *fr = NULL;
    13         FILE *fw = NULL;
    14         fr = fopen("data", "rb");
    15         fw = fopen("dataout", "wb");
    16         test(fr, fw);
    17         fclose(fr);
    18         fclose(fw);
    19         return 0;
    20 }

    2、输出和为一个给定整数的所有组合

    例如n=5

    5=1+4;5=2+3(相加的数不能重复)

    则输出

    1,4;2,3。

     1 #include <stdio.h>
     2 int main(void)
     3 {
     4     unsigned long int i,j,k; 
     5     printf("please input the number
    ");
     6     scanf("%d",&i);
     7     if( i % 2 == 0)
     8         j = i / 2;
     9   else
    10       j = i / 2 + 1; 
    11     printf("The result is 
    ");
    12     for(k = 0; k < j; k++)
    13      printf("%d = %d + %d
    ",i,k,i - k);
    14 
    15     return 0;
    16 }

     1 #include <stdio.h>
     2 void main()
     3 {
     4     unsigned long int a,i=1;
     5     scanf("%d",&a);
     6     if(a%2==0)
     7     {
     8          for(i=1;i<a/2;i++)
     9          printf("%d",a,a-i);
    10     }
    11     else
    12         for(i=1;i<=a/2;i++)
    13             printf(" %d, %d",i,a-i);
    14 }  

    3、递规反向输出字符串的例子,可谓是反序的经典例程.

    void inverse(char *p)
    {
        if( *p = = '' )
            return;
        inverse( p+1 );
        printf( "%c", *p );
    } 
    
    int main(int argc, char *argv[])
    {
        inverse("abc");
        return 0;
    }

    4、写一段程序,找出数组中第k大小的数,输出数所在的位置。例如{2,4,3,4,7}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。函数接口为:int find_orderk(const int* narry,const int n,const int k)

    要求算法复杂度不能是O(n^2)

    谢谢!

    可以先用快速排序进行排序,其中用另外一个进行地址查找

    代码如下,在VC++6.0运行通过。给分吧^-^ 

      1 //快速排序 
      2 
      3 #include<iostream>
      4 usingnamespacestd;
      5 
      6  
      7 
      8 intPartition (int*L,intlow,int high)
      9 
     10 {
     11 
     12 inttemp = L[low];
     13 
     14 intpt = L[low];
     15 
     16  
     17 
     18 while (low < high)
     19 
     20 {
     21 
     22 while (low < high && L[high] >= pt)
     23 
     24 --high;
     25 
     26 L[low] = L[high];
     27 
     28 while (low < high && L[low] <= pt)
     29 
     30 ++low;
     31 
     32 L[low] = temp;
     33 
     34 }
     35 
     36 L[low] = temp;
     37 
     38  
     39 
     40 returnlow;
     41 
     42 }
     43 
     44  
     45 
     46 voidQSort (int*L,intlow,int high)
     47 
     48 {
     49 
     50 if (low < high)
     51 
     52 {
     53 
     54 intpl = Partition (L,low,high);
     55 
     56  
     57 
     58 QSort (L,low,pl - 1);
     59 
     60 QSort (L,pl + 1,high);
     61 
     62 }
     63 
     64 }
     65 
     66  
     67 
     68 intmain ()
     69 
     70 {
     71 
     72 intnarry[100],addr[100];
     73 
     74 intsum = 1,t;
     75 
     76  
     77 
     78 cout << "Input number:" << endl;
     79 
     80 cin >> t;
     81 
     82  
     83 
     84 while (t != -1)
     85 
     86 {
     87 
     88 narry[sum] = t;
     89 
     90 addr[sum - 1] = t;
     91 
     92 sum++;
     93 
     94  
     95 
     96 cin >> t;
     97 
     98 }
     99 
    100  
    101 
    102 sum -= 1;
    103 
    104 QSort (narry,1,sum);
    105 
    106  
    107 
    108 for (int i = 1; i <= sum;i++)
    109 
    110 cout << narry[i] << '	';
    111 
    112 cout << endl;
    113 
    114  
    115 
    116 intk;
    117 
    118 cout << "Please input place you want:" << endl;
    119 
    120 cin >> k;
    121 
    122  
    123 
    124 intaa = 1;
    125 
    126 intkk = 0;
    127 
    128 for (;;)
    129 
    130 {
    131 
    132 if (aa == k)
    133 
    134 break;
    135 
    136 if (narry[kk] != narry[kk + 1])
    137 
    138 {
    139 
    140 aa += 1;
    141 
    142 kk++;
    143 
    144 }
    145 
    146  
    147 
    148 }
    149 
    150  
    151 
    152 cout << "The NO." << k << "number is:" << narry[sum - kk] << endl;
    153 
    154 cout << "And it's place is:" ;
    155 
    156 for (i = 0;i < sum;i++)
    157 
    158 {
    159 
    160 if (addr[i] == narry[sum - kk])
    161 
    162 cout << i << '	';
    163 
    164 }
    165 
    166  
    167 
    168  
    169 
    170 return0;
    171 
    172 }

    5、两路归并排序

     1 Linklist *unio(Linklist *p,Linklist *q){
     2 
     3 linklist *R,*pa,*qa,*ra;
     4 
     5 pa=p;
     6 
     7 qa=q;
     8 
     9 R=ra=p;
    10 
    11 while(pa->next!=NULL&&qa->next!=NULL){
    12 
    13 if(pa->data>qa->data){
    14 
    15 ra->next=qa;
    16 
    17 qa=qa->next;
    18 
    19 }
    20 
    21 else{
    22 
    23 ra->next=pa;
    24 
    25 pa=pa->next;
    26 
    27 }
    28 
    29 }
    30 
    31 if(pa->next!=NULL)
    32 
    33 ra->next=pa;
    34 
    35 if(qa->next!=NULL)
    36 
    37 ra->next==qa;
    38 
    39 return R;
    40 
    41 }

    6、用递归算法判断数组a[N]是否为一个递增数组。

    递归的方法,记录当前最大的,并且判断当前的是否比这个还大,大则继续,否则返回false结束:

     1 bool fun( int a[], int n )
     2 
     3 {
     4 
     5 if( n= =1 )
     6 
     7 return true;
     8 
     9 if( n= =2 )
    10 
    11 return a[n-1] >= a[n-2];
    12 
    13 return fun( a,n-1) && ( a[n-1] >= a[n-2] );
    14 
    15 }

    7、单连表的建立,把'a'--'z'26个字母插入到连表中,并且倒叙,还要打印!

    方法1:

    typedef struct val

    {   int date_1;

        struct val *next;

    }*p; 

    void main(void)

    {   char c;    

        for(c=122;c>=97;c--)

           { p.date=c;

             p=p->next;

            } 

        p.next=NULL;

    }

    }

    方法2:

    node *p = NULL;

    node *q = NULL;

    node *head = (node*)malloc(sizeof(node));

    head->data = ' ';head->next=NULL;

    node *first = (node*)malloc(sizeof(node));

    first->data = 'a';first->next=NULL;head->next = first;

    p = first;

    int longth = 'z' - 'b';

    int i=0;

    while ( i<=longth )

    {

    node *temp = (node*)malloc(sizeof(node));

    temp->data = 'b'+i;temp->next=NULL;q=temp;

    head->next = temp; temp->next=p;p=q;

    i++;

    }

    print(head);

    8、请列举一个软件中时间换空间或者空间换时间的例子。

    void swap(int a,int b)

    {

    int c; c=a;a=b;b=a;

    }

    --->空优

    void swap(int a,int b)

    {

    a=a+b;b=a-b;a=a-b;

    }

    9、outputstr所指的值为123456789

    int continumax(char *outputstr, char *inputstr)

    {

    char *in = inputstr, *out = outputstr, *temp, *final;

    int count = 0, maxlen = 0;

    while( *in != '' )

    {

    if( *in > 47 && *in < 58 )

    {

    for(temp = in; *in > 47 && *in < 58 ; in++ )

    count++;

    }

    else

    in++;

    if( maxlen < count )

    {

    maxlen = count;

    count = 0;

    final = temp;

    }

    }

    for(int i = 0; i < maxlen; i++)

    {

    *out = *final;

    out++;

    final++;

    }

    *out = '';

    return maxlen;

    }

    10、不用库函数,用C语言实现将一整型数字转化为字符串

    方法1:

    int getlen(char *s){

        int n;

        for(n = 0; *s != ''; s++)

               n++;

        return n;

    }

    void reverse(char s[])

    {

       int c,i,j;

       for(i = 0,j = getlen(s) - 1; i < j; i++,j--){

           c = s[i];

           s[i] = s[j];

           s[j] = c;

       }

    }

    void itoa(int n,char s[])

    {

       int i,sign;

       if((sign = n) < 0)

            n = -n;

       i = 0;

       do{/*以反序生成数字*/

          s[i++] = n%10 + '0';/*get next number*/

       }while((n /= 10) > 0);/*delete the number*/

       if(sign < 0)

          s[i++] = '-';

       s[i] = '';

       reverse(s);

    }

    方法2:

    #include <iostream>

    using namespace std;

    void itochar(int num);

    void itochar(int num)

    {

    int i = 0;

    int j ;

    char stra[10];

    char strb[10];

    while ( num )

    {

    stra[i++]=num%10+48;

    num=num/10;

    }

    stra[i] = '';

    for( j=0; j < i; j++)

    {

    strb[j] = stra[i-j-1];

    }

    strb[j] = '';

    cout<<strb<<endl;

    }

    int main()

    {

    int num;

    cin>>num;

    itochar(num);

    return 0;

    }

    11、求组合数: 求n个数(1....n)中k个数的组合....

               如:combination(5,3)

      要求输出:543,542,541,532,531,521,432,431,421,321,

    #include<stdio.h>

    int pop(int *);

    int push(int );

    void combination(int ,int );

    int stack[3]={0};

    top=-1;

    int main()

    {

    int n,m;

    printf("Input two numbers: ");

    while( (2!=scanf("%d%*c%d",&n,&m)) )

    {

    fflush(stdin);

    printf("Input error! Again: ");

    }

    combination(n,m);

    printf(" ");

    }

    void combination(int m,int n)

    {

    int temp=m;

    push(temp);

    while(1)

    {

    if(1==temp)

    {

    if(pop(&temp)&&stack[0]==n) //当栈底元素弹出&&为可能取的最小值,循环退出

    break;

    }

    else if( push(--temp))

    {

    printf("%d%d%d  ",stack[0],stack[1],stack[2]);//§&auml;¨ì¤@?

    pop(&temp);

    }

    }

    }

    int push(int i)

    {

    stack[++top]=i;

    if(top<2)

    return 0;

    else

    return 1;

    }

    int pop(int *i)

    {

    *i=stack[top--];

    if(top>=0)

    return 0;

    else

    return 1;

    }

    12、用指针的方法,将字符串“ABCD1234efgh”前后对调显示

    #include <stdio.h>

    #include <string.h>

    #include <dos.h>

    int main()

    {

        char str[] = "ABCD1234efgh";

        int length = strlen(str);

        char * p1 = str;

        char * p2 = str + length - 1;

        while(p1 < p2)

        {

            char c = *p1;

            *p1 = *p2;

            *p2 = c;

            ++p1;

            --p2;

        }

        printf("str now is %s ",str);

        system("pause");

        return 0;

    }

    13、有一分数序列:1/2,1/4,1/6,1/8……,用函数调用的方法,求此数列前20项的和

    #include <stdio.h>

    double getValue()

    {

        double result = 0;

        int i = 2;

        while(i < 42)

        {

            result += 1.0 / i;//一定要使用1.0做除数,不能用1,否则结果将自动转化成整数,即0.000000

            i += 2;

        }

        return result;

    }

    int main()

    {

        printf("result is %f ", getValue());

        system("pause");

        return 0;

    }

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

    以7个数为例:

       {0,1,2,3,4,5,6,7} 0-->1-->2(删除)-->3-->4-->5(删除)-->6-->7-->0(删除),如此循环直到最后一个数被删除。

    方法1:数组

    #include <iostream>

    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<iostream>

    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<<p->data;

    return 0;

    }

    方法3:通用算法

    #include <stdio.h>

    #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 ",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;i<MAXLINE;i++) {

    a[i]=i;

    R[i]=i+1;

    }

    R[i-1]=0;

    find_n(a,R,K,index,values,2);

    printf("the value is %d,%d ",index,values);

    return 0;

    }

    15、实现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;

    }

    16、实现子串定位

    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;

    }

    17、已知一个单向链表的头,请写出删除其某一个结点的算法,要求,先找到此结点,然后删除。

    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)

    }

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

    #include<iostream.h>

    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;

    }

    19、写出程序把一个链表中的接点顺序倒排

    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;

    }

    20、写出程序删除链表中的所有接点

    void del_all(node *head)

    {

    node *p;

    while(head!=NULL)

    {

    p=head->next;

    free(head);

    head=p;

    }

    cout<<"释放空间成功!"<<endl;

    }

    21、两个字符串,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!='')

    {

    p++;

    }

    while(*q!=0)

    {

    *p=*q;

    p++;

    q++;

    }

    *p = '';

    }

    22、写一个函数,功能:完成内存之间的拷贝

    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 }

    23、公司考试这种题目主要考你编写的代码是否考虑到各种情况,是否安全(不会溢出)

    各种情况包括:

    1、参数是指针,检查指针是否有效

    2、检查复制的源目标和目的地是否为同一个,若为同一个,则直接跳出

    3、读写权限检查

    4、安全检查,是否会溢出

    memcpy拷贝一块内存,内存的大小你告诉它

    strcpy是字符串拷贝,遇到''结束

    /* 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);

    }

    24、两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串

    void insert(char *s, char *t, int i)

    {

    memcpy(&s[strlen(t)+i],&s[i],strlen(s)-i);

    memcpy(&s[i],t,strlen(t));

    s[strlen(s)+strlen(t)]='';

    }

    25、编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的。

    char * search(char *cpSource, char ch)

    {

             char *cpTemp=NULL, *cpDest=NULL;

             int iTemp, iCount=0;

             while(*cpSource)

             {

                     if(*cpSource == ch)

                     {

                              iTemp = 0;

                              cpTemp = cpSource;

                              while(*cpSource == ch)

    ++iTemp, ++cpSource;

                              if(iTemp > iCount)

    iCount = iTemp, cpDest = cpTemp;

            if(!*cpSource)

    break;

                     }

                     ++cpSource;

     }

     return cpDest;

    }     

    26、请编写一个 C 函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值。

    int search(char *cpSource, int n, char ch)

    {

             int i;

             for(i=0; i<n && *(cpSource+i) != ch; ++i);

             return i;

    }

    27、给定字符串A和B,输出A和B中的最大公共子串。

    比如A="aocdfe" B="pmcdfa" 则输出"cdf"

    */

    //Author: azhen

    #include<stdio.h>

    #include<stdlib.h>

    #include<string.h>

    char *commanstring(char shortstring[], char longstring[])

    {

    int i, j;

    char *substring=malloc(256);

    if(strstr(longstring, shortstring)!=NULL)              //如果……,那么返回shortstring

    return shortstring; 

    for(i=strlen(shortstring)-1;i>0; i--)                 //否则,开始循环计算

    {

    for(j=0; j<=strlen(shortstring)-i; j++){

    memcpy(substring, &shortstring[j], i);

    substring[i]='';

    if(strstr(longstring, substring)!=NULL)

    return substring;

    }

    }

    return NULL;

    }

    main()

    {

    char *str1=malloc(256);

    char *str2=malloc(256);

    char *comman=NULL;

    gets(str1);

    gets(str2);

    if(strlen(str1)>strlen(str2))                         //将短的字符串放前面

    comman=commanstring(str2, str1);

    else

    comman=commanstring(str1, str2);

    printf("the longest comman string is: %s ", comman);

    }

    28、写一个函数比较两个字符串str1和str2的大小,若相等返回0,若str1大于

    str2返回1,若str1小于str2返回-1

    int strcmp ( const char * src,const char * dst)

    {

            int ret = 0 ;

            while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)

    {

                    ++src;

    ++dst;

    }

            if ( ret < 0 )

                    ret = -1 ;

            else if ( ret > 0 )

                    ret = 1 ;

            return( ret );

    }

    29、求1000!的未尾有几个0(用素数相乘的方法来做,如72=2*2*2*3*3);

    求出1->1000里,能被5整除的数的个数n1,能被25整除的数的个数n2,能被125整除的数的个数n3,

    能被625整除的数的个数n4.

    1000!末尾的零的个数=n1+n2+n3+n4;

    #include<stdio.h>

    #define NUM 1000

    int find5(int num){

    int ret=0;

    while(num%5==0){

    num/=5;

    ret++;

    }

    return ret;

    }

    int main(){

    int result=0;

    int i;

    for(i=5;i<=NUM;i+=5)

    {

    result+=find5(i);

    }

    printf(" the total zero number is %d ",result);

    return 0;

    }

    30、有双向循环链表结点定义为:

    struct node

    { int data;

    struct node *front,*next;

    };

    有两个双向循环链表A,B,知道其头指针为:pHeadA,pHeadB,请写一函数将两链表中data值相同的结点删除

    BOOL DeteleNode(Node *pHeader, DataType Value)

    {

    if (pHeader == NULL) return;

    BOOL bRet = FALSE;

    Node *pNode = pHead;

    while (pNode != NULL)

    {

    if (pNode->data == Value)

    {

    if (pNode->front == NULL)

    {

    pHeader = pNode->next;

    pHeader->front = NULL;

    }

    else

    {

    if (pNode->next != NULL)

    {

    pNode->next->front = pNode->front;

    }

    pNode->front->next = pNode->next;

    }

    Node *pNextNode = pNode->next;

    delete pNode;

    pNode = pNextNode;

    bRet = TRUE;

    //不要break或return, 删除所有

    }

    else

    {

    pNode = pNode->next;

    }

    }

    return bRet;

    }

    void DE(Node *pHeadA, Node *pHeadB)

    {

    if (pHeadA == NULL || pHeadB == NULL)

    {

    return;

    }

    Node *pNode = pHeadA;

    while (pNode != NULL)

    {

    if (DeteleNode(pHeadB, pNode->data))

    {

    if (pNode->front == NULL)

    {

    pHeadA = pNode->next;

    pHeadA->front = NULL;

    }

    else

    {

    pNode->front->next = pNode->next;

    if (pNode->next != NULL)

    {

    pNode->next->front = pNode->front;

    }

    }

    Node *pNextNode = pNode->next;

    delete pNode;

    pNode = pNextNode;

    }

    else

    {

    pNode = pNode->next;

    }

    }

    }

    31、编程实现:找出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串为"cad"

    int GetCommon(char *s1, char *s2, char **r1, char **r2)

    {

    int len1 = strlen(s1);

    int len2 = strlen(s2);

    int maxlen = 0;

    for(int i = 0; i < len1; i++)

    {

    for(int j = 0; j < len2; j++)

    {

    if(s1[i] == s2[j])

    {

    int as = i, bs = j, count = 1;

    while(as + 1 < len1 && bs + 1 < len2 && s1[++as] == s2[++bs])

    count++;

    if(count > maxlen)

    {

    maxlen = count;

    *r1 = s1 + i;

    *r2 = s2 + j;

    }

    }

    }

    }

    32、编程实现:把十进制数(long型)分别以二进制和十六进制形式输出,不能使用printf系列库函数

    char* test3(long num) {

    char* buffer = (char*)malloc(11);

    buffer[0] = '0';

    buffer[1] = 'x';

    buffer[10] = '';

    char* temp = buffer + 2;

    for (int i=0; i < 8; i++) {

    temp[i] = (char)(num<<4*i>>28);

    temp[i] = temp[i] >= 0 ? temp[i] : temp[i] + 16;

    temp[i] = temp[i] < 10 ? temp[i] + 48 : temp[i] + 55;

    }

    return buffer;

    }

    33、输入N, 打印 N*N 矩阵

    比如 N = 3,打印:

    1  2  3

    8  9  4

    7  6  5

    N = 4,打印:

    1   2   3   4

    12  13  14  5

    11  16  15  6

    10  9   8   7

    解答:

    1 #define N 15

    int s[N][N];

    void main()

    {

    int k = 0, i = 0, j = 0;

    int a = 1;

    for( ; k < (N+1)/2; k++ )

    {

    while( j < N-k ) s[i][j++] = a++; i++; j--;

    while( i < N-k ) s[i++][j] = a++; i--; j--;

    while( j > k-1 ) s[i][j--] = a++; i--; j++;

    while( i > k )   s[i--][j] = a++; i++; j++;

    }

    for( i = 0; i < N; i++ )

    {

    for( j = 0; j < N; j++ )

    cout << s[i][j] << ' ';

    cout << endl;

    }

    }

    2 define MAX_N  100

    int matrix[MAX_N][MAX_N];

    /*

     *(x,y):第一个元素的坐标

     * start:第一个元素的值

     * n:矩阵的大小

     */

    void SetMatrix(int x, int y, int start, int n) {

        int i, j;

        if (n <= 0)    //递归结束条件

            return;

        if (n == 1) {  //矩阵大小为1时

            matrix[x][y] = start;

            return;

        }

        for (i = x; i < x + n-1; i++)   //矩阵上部

            matrix[y][i] = start++;

        for (j = y; j < y + n-1; j++)   //右部

            matrix[j][x+n-1] = start++;

        for (i = x+n-1; i > x; i--)     //底部

            matrix[y+n-1][i] = start++;

        for (j = y+n-1; j > y; j--)     //左部

            matrix[j][x] = start++;

        SetMatrix(x+1, y+1, start, n-2);   //递归

    }

    void main() {

       int i, j;

       int n;

       scanf("%d", &n);

       SetMatrix(0, 0, 1, n);

      

       //打印螺旋矩阵

       for(i = 0; i < n; i++) {

          for (j = 0; j < n; j++)

    printf("%4d", matrix[i][j]);

          printf(" ");

       }

    }

    34、斐波拉契数列递归实现的方法如下:

     int  Funct( int n )

    {

       if(n==0) return 1;

       if(n==1) return 1;

       retrurn  Funct(n-1) + Funct(n-2);

    }

    请问,如何不使用递归,来实现上述函数?

    请教各位高手!

    解答:int  Funct( int n )  //  n 为非负整数

    {

       int a=0;

       int b=1;

       int c;

       if(n==0) c=1;

       else if(n==1) c=1;

       else for(int i=2;i<=n;i++)  //应该n从2开始算起

       {

         c=a+b;

         a=b;

         b=c;

       }

       return c;

    }

    解答:

    现在大多数系统都是将低字位放在前面,而结构体中位域的申明一般是先声明高位。

    100  的二进制是 001 100 100

    低位在前   高位在后 

    001----s3

    100----s2

    100----s1

    所以结果应该是 1

    如果先申明的在低位则:

    001----s1

    100----s2

    100----s3

    结果是 4

    1、原题跟little-endian,big-endian没有关系

    2、原题跟位域的存储空间分配有关,到底是从低字节分配还是从高字节分配,从Dev C++和VC7.1上看,都是从低字节开始分配,并且连续分配,中间不空,不像谭的书那样会留空位

    3、原题跟编译器有关,编译器在未用堆栈空间的默认值分配上有所不同,Dev C++未用空间分配为

    01110111b,VC7.1下为11001100b,所以在Dev C++下的结果为5,在VC7.1下为1。

    注:PC一般采用little-endian,即高高低低,但在网络传输上,一般采用big-endian,即高低低高,华为是做网络的,所以可能考虑big-endian模式,这样输出结果可能为4

    35、判断一个字符串是不是回文

    int IsReverseStr(char *aStr)

    {

    int i,j;

    int found=1;

    if(aStr==NULL)

    return -1;

    j=strlen(aStr);

    for(i=0;i<j/2;i++)

    if(*(aStr+i)!=*(aStr+j-i-1))

    {

    found=0;

    break;

    }

    return found;

    }

    36、Josephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

    数组实现:

    #include <stdio.h>

    #include <malloc.h>

    int Josephu(int n, int m)

    {

      int flag, i, j = 0;

      int *arr = (int *)malloc(n * sizeof(int));

      for (i = 0; i < n; ++i)

        arr[i] = 1;

      for (i = 1; i < n; ++i)

      {

        flag = 0;

        while (flag < m)

        {

          if (j == n)

            j = 0;

          if (arr[j])

            ++flag;

          ++j;

        }

        arr[j - 1] = 0;

        printf("第%4d个出局的人是:%4d号 ", i, j);

      }

      free(arr);

      return j;

    }

    int main()

    {

      int n, m;

      scanf("%d%d", &n, &m);

      printf("最后胜利的是%d号! ", Josephu(n, m));

      system("pause");

      return 0;

    }

    链表实现:

    #include <stdio.h>

    #include <malloc.h>

    typedef struct Node

    {

      int index;

      struct Node *next;

    }JosephuNode;

    int Josephu(int n, int m)

    {

      int i, j;

      JosephuNode *head, *tail;

      head = tail = (JosephuNode *)malloc(sizeof(JosephuNode));

      for (i = 1; i < n; ++i)

      {

        tail->index = i;

        tail->next = (JosephuNode *)malloc(sizeof(JosephuNode));

        tail = tail->next;

      }

      tail->index = i;

      tail->next = head;

      for (i = 1; tail != head; ++i)

      {

        for (j = 1; j < m; ++j)

        {

          tail = head;

          head = head->next;

        }

        tail->next = head->next;

        printf("第%4d个出局的人是:%4d号 ", i, head->index);

        free(head);

        head = tail->next;

      }

      i = head->index;

      free(head);

      return i;

    }

    int main()

    {

      int n, m;

      scanf("%d%d", &n, &m);

      printf("最后胜利的是%d号! ", Josephu(n, m));

      system("pause");

      return 0;

    }

    37、已知strcpy函数的原型是:

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

        1.不调用库函数,实现strcpy函数。

        2.解释为什么要返回char *。

        解说:

        1.strcpy的实现代码

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

            {

                    if ((strDest==NULL)||(strSrc==NULL)) file://[/1]

                            throw "Invalid argument(s)"; //[2]

                    char * strDestCopy=strDest;  file://[/3]

                    while ((*strDest++=*strSrc++)!=''); file://[/4]

                    return strDestCopy;

            }

        错误的做法:

        [1]

        (A)不检查指针的有效性,说明答题者不注重代码的健壮性。

        (B)检查指针的有效性时使用((!strDest)||(!strSrc))或(!(strDest&&strSrc)),说明答题者对C语言中类型的隐式转换没有深刻认识。在本例中char *转换为bool即是类型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。所以C++专门增加了bool、true、false三个关键字以提供更安全的条件表达式。

        (C)检查指针的有效性时使用((strDest==0)||(strSrc==0)),说明答题者不知道使用常量的好处。直接使用字面常量(如本例中的0)会减少程序的可维护性。0虽然简单,但程序中可能出现很多处对指针的检查,万一出现笔误,编译器不能发现,生成的程序内含逻辑错误,很难排除。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。

        [2]

        (A)return new string("Invalid argument(s)");,说明答题者根本不知道返回值的用途,并且他对内存泄漏也没有警惕心。从函数中返回函数体内分配的内存是十分危险的做法,他把释放内存的义务抛给不知情的调用者,绝大多数情况下,调用者不会释放内存,这导致内存泄漏。

        (B)return 0;,说明答题者没有掌握异常机制。调用者有可能忘记检查返回值,调用者还可能无法检查返回值(见后面的链式表达式)。妄想让返回值肩负返回正确值和异常值的双重功能,其结果往往是两种功能都失效。应该以抛出异常来代替返回值,这样可以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。

        [3]

        (A)忘记保存原始的strDest值,说明答题者逻辑思维不严密。

        [4]

        (A)循环写成while (*strDest++=*strSrc++);,同[1](B)。

        (B)循环写成while (*strSrc!='') *strDest++=*strSrc++;,说明答题者对边界条件的检查不力。循环体结束后,strDest字符串的末尾没有正确地加上''。

  • 相关阅读:
    OTA JAR和JAD的mime不同
    document.getElementById('selCatalog').remove(i)突然无效???!
    判断WAP1.1和WAP2.0并解析为wml或xhtml
    IE和firefox下显示html内容
    unixrisk tip
    unixftp windows
    unixstdin/stdout/stderr
    峰鸟摄影
    linuxgrep commond
    unixtutorial(recommended)
  • 原文地址:https://www.cnblogs.com/ordinary-world/p/9973019.html
Copyright © 2020-2023  润新知