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字符串的末尾没有正确地加上''。

原文地址:https://www.cnblogs.com/ordinary-world/p/9973019.html