C++面试题源码

电脑硬盘坏过一次,请人挽回了些数据,但很多东西还是丢了。偶然翻出来的这些源码,是以前整理的一些面试中常用的编程题,在VC上测试过,但不保证完全没有问题。发到网上就不怕再坏硬盘了。
1.写一函数int fun(char *p)判断一字符串是否为回文,是返回1,不是返回0,出错返回-1
//答案:一、
int fun(char *p)

 if(p==NULL) 
  return -1; 
 else 
 { 
  int length = 0; 
  int i = 0; 
  int judge = 1; 
  length = (int)strlen(p); 
  for(i=0; i <length/2; i++) 
  {   
   if(p[i] != p[length-1-i])   
    judge = 0;   
   break; 
  } 
  if(judge == 0)   
   return 0; 
  else   
   return 1; 
 }
//答案:二、
int fun1(char *p)
{
 if(p==NULL) 
  return -1;
 int len = (int)strlen(p) - 1;
 char *q = p + len;
 while (p < q)
 {
  if ((*p++) != (*q--))
   return 0;
 }
 return 1;


2.类的知识 (非常不错的一道题目)..
#include <iostream.h>
class human
{
public:
 human()
 {
  human_num++;
 }; //默认构造函数
 static int human_num;     //静态成员
 ~human()
 {
  human_num--;
  print();
 }
 void print()             //
 {
  cout<<"human num is: "<<human_num<<endl;
 }
protected:
private:
};
int human::human_num = 0;   //类中静态数据成员在外部定义,仅定义一次
human f1(human x)
{
 x.print();
 return x;
}
int main(int argc, char* argv[])
{
 human h1; //调用默认构造函数,human_num变为1
 h1.print(); // 打印Human_man:1
 human h2 = f1(h1); //先调用函数f1(),输出human_num:1,而后输出human_num为0,
 h2.print();//打印输出:human_num:0
 return 0;
} //依次调用两个析构函数:输出:human_num:-1,human_num:-2;
输出:
1
1
0
0
-1
-2
----------------------------
分析:
human h1; //调用构造函数,---hum_num = 1;
h1.print(); //输出:"human is 1"
human h2 = f1(h1); //再调用f1(h1)的过程中,由于函数参数是按值传递对象,调用默认的复制构造函数,h2并没有调用定义的构造函数.

3.深度遍历二叉树。
struct Node
{
 int Data;  //我自己添加的,方便测试
 Node *Parent;
 Node *Left, *Right;
};
void Through(Node *Root)

 cout<<Root->Data<<endl;   
 if(Root->Left != NULL)
  Through(Root->Left);
 if(Root->Right != NULL)
  Through(Root->Right); 
}

4.输入年月日时分秒,输出年月日时分秒的下一秒,输出仍然在原内存空间
/*输入年月日时分秒,输出年月日时分秒的下一秒,输出仍然在原内存空间*/
void NextMinute(int *nYear,int *nMonth,int *nDate,int *nHour,int *nMinute,int *nSecond)

 int nDays; 
 (*nSecond)++;  // 秒加1
 if(*nSecond>=60)  // 秒满60,做出特殊处理,下面时,日,月等类同
 {   
  *nSecond=0;   
  (*nMinute)++;   
  if(*nMinute>=60)   
  {    
   *nMinute=0;     
   (*nHour)++;     
   if(*nHour>=24)     
   {       
    *nHour=0;       
    (*nDate)++;       
    switch(*nMonth)       
    {        
    case 1:         
    case 3:         
    case 5:         
    case 7:         
    case 8:        
    case 10:         
    case 12:           
     nDays=31;        
     break;         
    case 2:// 判断闰年           
     if(*nYear%400==0 || *nYear%100!=0&&*nYear%4==0)     
     {          
      nDays=29;         
     }         
     else        
     {       
      nDays=28;  
     }        
     break;   
    default:     
     nDays=30;  
     break;     
    }      
    if(*nDate>nDays)
    {         
     *nDate=1;
     (*nMonth)++;  
     if(*nMonth>12)     
     {      
      *nMonth=1;   
      (*nYear)++;  
     }   
    }     
   }  
  }
 }
}

5.atoi 函数
/** atoi 函数 **/
int my_atoi01(const char *str)
{
 long int v=0;
 int sign = 0;
 while ( *str == ' ')
  str++;
 if(*str == '-'||*str == '+')
  sign = *str++;
 while (isdigit(*str))
 {
  v = v*10 + *str - '0';
  str++;
 }
 return sign == '-' ? -v:v;
}

6.itoa 函数
/** itoa 函数 **/
char *my_itoa(int val, char *buf, int radix)
{
 char *p, *first, temp;
 int digital;
 p = buf;
 if (val < 0)
 {
  *p++ = '-';
  val = -val;
 }
 first = p;
 do
 {
  digital = val%radix;
  val /= radix;
  if (digital > 9)
   *p++ = (char)(digital - 10 + 'A');
  else
   *p++ = (char)(digital + '0');
 }while(val > 0);
 *p-- = '\0';
 do
 {
  temp = *p;
  *p = *first;
  *first = temp;
  p--;
  first++;
 }while(first < p);
 return buf;
}

7.atol 函数
/** atol 函数 **/
long  my_atol( const char *nptr  )
{
 int c;              /* current char */
 long total;        /* current total */
 int sign;          /* if '-', then negative, otherwise positive */
   
 /* skip whitespace */
 while ( isspace((int)(unsigned char)*nptr) )
  ++nptr;
 c = (int)(unsigned char)*nptr++;
 sign = c;          /* save sign indication */
 if (c == '-' || c == '+')
  c = (int)(unsigned char)*nptr++;    /* skip sign */
 total = 0;
 while (isdigit(c))
 {
  total = 10 * total + (c - '0');    /* accumulate digit */
  c = (int)(unsigned char)*nptr++;    /* get next char */
 }
 if (sign == '-')
  return -total;
 else
  return total;  /* return result, negated if necessary */
}

8.strlen 函数
/** strlen 函数 **/
size_t strlen ( const char * str )
{
        const char *eos = str;
        while( *eos++ )
;
        return( (int)(eos - str - 1) );
}

9.strstr函数
/** strstr函数 **/
char * strstr (const char * str1,const char * str2 )
{
 char *cp = (char *) str1;
 char *s1, *s2;
 if ( !*str2 )
  return((char *)str1);
 while (*cp)
 {
  s1 = cp;
  s2 = (char *) str2;
  while ( *s1 && *s2 && !(*s1-*s2) )
   s1++, s2++;
  if (!*s2)
   return(cp);
  cp++;
 }
 return(NULL);
}

10. strcat函数
/** strcat函数 **/
char * strcat (char * dst,const char * src )
{
        char * cp = dst;
        while( *cp )
                cp++;                   /* find end of dst */
        while( *cp++ = *src++ ) ;       /* Copy src to end of dst */
        return( dst );                  /* return dst */
}

11. strncat函数
/** strncat函数 **/
char * strncat (char * front,const char * back,size_t count )
{
        char *start = front;
        while (*front++)
   ;
  front--;
        while (count--)
   if (!(*front++ = *back++))
    return(start);
        *front = '\0';
        return(start);
}

12. strcpy函数
/** strcpy函数 **/
char * strcpy(char * dst, const char * src)
{
        char * cp = dst;
        while( *cp++ = *src++ )
   ;               /* Copy src over dst */
        return( dst );
}

13. strncpy函数
/** strncpy函数 **/
char * strncpy (char * dest,const char * source,size_t count)
{
        char *start = dest;
        while (count && (*dest++ = *source++))    /* copy string */
   count--;
        if (count)                             /* pad out with zeroes */
   while (--count)
    *dest++ = '\0';
        return(start);
}

14. strcmp函数
/** strcmp函数 **/
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 );
}

15. strncmp函数
/** strncmp函数 **/
int strncmp (const char * first,const char * last,size_t count)
{
        if (!count)
   return(0);
        while (--count && *first && *first == *last)
        {
                first++;
                last++;
        }

        return( *(unsigned char *)first - *(unsigned char *)last );
}

16. memset函数
/** memset函数 **/
void * memset (void *dst,int val,size_t count)
{
        void *start = dst;
        while (count--)
  {
                *(char *)dst = (char)val;
                dst = (char *)dst + 1;
        }
        return(start);
}

17. memcpy函数
/** memcpy函数 **/
void * memcpy (void * dst, const void * src,size_t count)
{
        void * ret = dst;
        while (count--) {
                *(char *)dst = *(char *)src;
                dst = (char *)dst + 1;
                src = (char *)src + 1;
        }
        return(ret);
}

18. memcmp函数
/** memcmp函数 **/
int memcmp ( const void * buf1, const void * buf2, size_t count )
{
        if (!count)
                return(0);
        while ( --count && *(char *)buf1 == *(char *)buf2 ) {
                buf1 = (char *)buf1 + 1;
                buf2 = (char *)buf2 + 1;
        }
        return( *((unsigned char *)buf1) - *((unsigned char *)buf2) );
}


19.编写用C语言实现的求n阶阶乘问题的递归算法:
答:
long int fact(int n)
{
 if(n==0||n==1)
  return 1;
 else
  return n*fact(n-1);
}

20.二分查找算法:
1) 递归方法实现:
/*在下届为low,上界为high的数组a中折半查找数据元素x*/
int BSearch(int a[],int x,int low,int high)
{
 int mid;
 if(low>high)
  return -1;
 mid=(low+high)/2;
 if(x==a[mid])
  return mid;
 if(x<a[mid])
  return(BSearch(a,x,low,mid-1));
 else
  return(BSearch(a,x,mid+1,high));
}
2) 非递归方法实现:
//2) 非递归方法实现:
int BSearch1(int a[], int key,int n)
{
 int low,high,mid;
 low=0;
 high=n-1;
 while(low<=high)
 {
  mid=(low+high)/2;
  if(a[mid]==key)
   return mid;
  else
   if(a[mid]<key)
    low=mid+1;
   else
    high=mid-1;
 }
 return -1;
}

21.递归计算如下递归函数的值(斐波拉契):
f(1)=1
f(2)=1
f(n)=f(n-1)+f(n-2)   n>2
解:非递归算法:
int f(int n)
{
 if(n==1 || n==2)
  return 1;
 int i,s,s1,s2;
 s1=1;   /*s1用于保存f(n-1)的值*/
 s2=1;   /*s2用于保存f(n-2)的值*/
 s=1;
 for(i=3;i<=n;i++)
 {
  //s=s2+s1;
  //s2=s1;
  //s1=s;
  s = s2 + s1;  我改的代码,感觉读得懂些
  s1 = s2;
  s2 = s;
 }
 return(s);
}
递归算法:
int f1(int n)
{
 if(n==1||n==2)
  return 1;
 else
  return (f1(n-1)+f1(n-2));
}

22.冒泡排序:
答:
///时间复杂度为0(n*n);
void BubbleSort(int x[],int n) 
{
 int i,j;
 int temp;
 for(i=1;i<n;i++)
  for(j=0;j<n-i;j++)   
  {
   if(x[j]>x[j+1])
   {
    temp=x[j];
    x[j]=x[j+1];
    x[j+1]=temp;
   }
  }
}

23.C语言 文件读写
#include "stdio.h"
main()
{
 FILE *fp;
 char ch,filename[10];
 scanf("%s",filename);
 if((fp=fopen(filename,"w")==NULL)
 {
  printf("cann't open filen");
  exit(0);
 }
 ch=getchar();
 while(ch!='#')
 {
  fputc(ch,fp);
  putchar(ch);
  ch=getchar();
 }
 fclose(fp);
}


24.编写反转字符串的程序,要求优化速度、优化空间。
/反转字符串的程序,要求优化速度和空间
void str_revert(char* argv,int len)
{
 int i = 0;
 int mid = len/2;
 char *head = argv;
 char *end = argv+len-1;
 char tmp = 0;
 for(i=0; i<mid; i++)
 {
  tmp = *head;
  *head = *end;
  *end = tmp;
  head++;
  end--;
 }
}
25.给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。
//洗牌算法
struct pukepai{
 char d;      //点
 char s;        //花色
};   
char dian(int i)
{
 switch(i)
 {
 case 0:
  return 'K';
 case 1:
  return 'A';
 case 10:
  return 'T';
 case 11:
  return 'J';
 case 12:
  return 'Q';
 default:
  return i+48;    ???????????????不懂
 }
}
void display()
{
 pukepai p[54];
 int temp[54],tem,i,j;
 for(i=0;i<54;i++)
  temp[i]=i+1;
 srand(time(0));
 for(i=0;i<54;i++)       //洗牌 1---54的随机数
 {
  tem=rand()%54;
  j=temp[i];
  temp[i]=temp[tem];    
  temp[tem]=j;
 }
 for(i=0;i<54;i++)    //赋值 并显示
 {
  if(temp[i]==54)
   p[i].d='S',p[i].s=0;  //大S
  else
   if(temp[i]==53)
    p[i].d='s',p[i].s=0;   //小s
   else
   {
    p[i].d=dian(temp[i]%13);
    p[i].s=(temp[i]-1)/13+3;
   }
 }
 for(i=0;i<54;i++)
 {
  cout<<p[i].s<<p[i].d<<"  "; 
  if((i+1)%5 ==0 )
   cout<<endl;
 }
 cout<<endl;

26.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
anSwer 记住,这种题目往往就是考你对边界的考虑情况。编程除了技术上的熟练以外,细心也是非常重要的。其实很多编程的大师可能并不是有特别的技术,往往就是他们非常的耐心和细心,记住:编程是计算机科学中最基本的工作,它是最容易去掌握的,耐心点,细心点你一定能够学好它。代码看下面:
char* myStrcpy(char* s,char* a,char* b,char n)
{
 int aLen = strlen(a),bLen = strlen(b);
 if(n > aLen || n > bLen)
  return NULL; // Error
 for(int i = 0;i < aLen + bLen - n;i++)
  if(i < aLen - n)
   s[i] = a[i];
  else
   s[i] = b[i - aLen + n];
 s[i] = '\0';
 return s;
}

27.怎样编写一个程序,把一个有序整数数组放到二叉树中?
ANSWER :二叉搜索树的建树方法。简单的递归结构。实在不理解,干脆记下来好了。关于树的算法设计一定要联想到递归,因为树本身就是递归的定义。这里的递归应该是理所当然的吧,不过,学会把递归改称非递归也是一种必要的技术。毕竟,递归会造成栈溢出,关于系统底层的程序中不到非不得以最好不要用。但是对某些数学问题,就一定要学会用递归去解决。
void insertNode(bTree** root,int val)
{
 bTree* newNode = (bTree* ) malloc(sizeof(bTree));
 newNode->data = val;
 newNode->lChild = NULL;
 newNode->rChild = NULL;
 if(!(*root))
  *root = newNode;
 else
  if(newNode->data < (*root)->data)
   insertNode(&(*root)->lChild,val);
  else
   insertNode(&(*root)->rChild,val); 
}

28.怎样从顶部开始逐层打印二叉树结点数据?请编程。
ANSWER 二叉树的层次遍历没什么好说的,如果你不会还是早点把基础复习一下。一个劲的往后学,才会发现原来最最重要的还是以前最基础最简单的。
typedef struct myBinaryTree
{
 int data;
 struct myBinaryTree* lChild;
 struct myBinaryTree* rChild;
} bTree;
struct myQueen
{
 bTree* que[QSIZE];
 int front;
 int rear;
} binQueue; // Global var
void initQueue()
{
 // front == real makes the queue empty
 binQueue.rear = QSIZE - 1;
 binQueue.front = binQueue.rear;
 for(int i = 0;i < QSIZE;i++)
  binQueue.que[i] = NULL;
}
int enQueue(bTree* newNode)
{
 if(binQueue.front >= 1)
  binQueue.que[binQueue.front--] = newNode;

 else
  return 0;
 return 1;
}
bTree* deQueue()
{
 int t;
 if(binQueue.front != binQueue.rear)
 {
  t = binQueue.rear;
  binQueue.rear--;
  return binQueue.que[t];
 }
 else
  return NULL;
}
int levelTraversal(bTree** root)
{
 initQueue();
 bTree* lc = (bTree* ) malloc(sizeof(bTree));
 bTree* rc = (bTree* ) malloc(sizeof(bTree));
 bTree* p = (bTree* ) malloc(sizeof(bTree));
 if((!lc) || (!rc) || (!p))
 {
  printf("OVERFLOW\n");
  exit(OVERFLOW); // Allocation Error
 }
 p = *root;
 if(!p)
 {
  printf("Empty Tree,build it first !\n");
  return 0;
 }
 enQueue(p); // enqueue the root of the tree
 while (binQueue.front != binQueue.rear)
 {
  p = deQueue();
  printf("%d ",p->data);
  lc = p->lChild;
  rc = p->rChild;
  if(lc != NULL)
   enQueue(lc);
  if(rc != NULL)
   enQueue(rc);
 }
 printf("\n");
 return 1;
}

29.怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)?
ANSWER 前面说了,最基本的是最重要的。线性数据结构是学习数据结构的入门,一定要掌握好。微软的题目还是跟国内的公司不一样。国内的一上来就是些概念,跟考历史一样。
typedef struct listNode
{
 struct listNode* link;
 int data;
}node;
node* getNode(node* newNode,int val)
{
 if(!newNode)
  exit(OVERFLOW);
 newNode->link = NULL;
 newNode->data = val;
 return newNode;
}
/*
Insert a new node after p
*/
int insertNode(node* prev,node* newNode)
{
 if(!prev) return 0;
 newNode->link = prev->link;
 prev->link = newNode;
 return 1;
}
/*
delete the node after the node prev
*/
int eraseNode(node*prev,node* p)
{
 if(p == NULL)
  return 0;
 prev->link = p->link;
 free(p);
 return 1;
}
void buildList(node* head)
{
 int value;
 node* newNode = (node* ) malloc(sizeof(node));
 node* p = head;
 scanf("%d",&value);
 while(value != -1){
  newNode = getNode(newNode,value);
  insertNode(p,newNode);
  p = p->link;
  newNode = (node* ) malloc(sizeof(node));
  scanf("%d",&value);
 }
}
int reverseList(node* head)
{
 node* p = head->link;
 node* q = p->link;
 if(p == NULL){
  printf("The list is empty!\n");
  return 0;
 }
 while(q != NULL){
  node* newNode = (node* ) malloc(sizeof(node));
  newNode = getNode(newNode,q->data);
  insertNode(head,newNode);
  eraseNode(p,q);
  q = (node* ) malloc(sizeof(node)); // Allocate again
  q = p->link;
 }
 p->link = NULL;
 return 1;
}

30.将以空格为分隔符分隔的字符串逆序打印,但单词不逆序。例如“Hello world Welcome to China”的打印结果为“China to Welcome world Hello”。

void print_word(const char * str, int start, int end)
{
 int i;
 for (i = start; i < end; ++i)
 {
  printf("%c", str[i]);
 }
}

/* Reversely print string str. */
void reversely_print_string(const char * str)
{
 int len, i, end;
 len = strlen(str);
 end = len;
 for (i = len - 1; i >= 0; --i)
 {
  if (' ' == str[i])
  {
   /* Print the word after this space. */
   print_word(str, i + 1, end);
   /* Print the space. */
   printf("%c", str[i]);
   /* Set the right boundary of the previous word. */
   end = i;
  }
 }
 /* Print the first word. */
 print_word(str, 0, end);
}


31.编写类String 的构造函数、析构函数和赋值函数
class String
{
public:
 String(const char *str = NULL); // 普通构造函数
 String(const String &other); // 拷贝构造函数
 ~ String(void); // 析构函数
 String & operator =(const String &other); // 赋值函数
private:
 char *m_data; // 用于保存字符串
};

// 请编写String 的上述4 个函数。
// 标准答案:
// String 的析构函数
String::~String(void) // 3 分
{
 delete [] m_data;
 // 由于m_data 是内部数据类型,也可以写成 delete m_data;
}

// String 的普通构造函数
String::String(const char *str) // 6 分
{
 if(str==NULL)
 {
  m_data = new char[1]; // 若能加 NULL 判断则更好
  *m_data = '\0';
 }
 else
 {
  int length = strlen(str);
  m_data = new char[length+1]; // 若能加 NULL 判断则更好
  strcpy(m_data, str);
 }
}

// 拷贝构造函数
String::String(const String &other) // 3 分
{
 int length = strlen(other.m_data);
 m_data = new char[length+1]; // 若能加 NULL 判断则更好
 strcpy(m_data, other.m_data);
}

// 赋值函数
String & String::operator =(const String &other) // 13 分
{
 // (1) 检查自赋值 // 4 分
 if(this == &other)
  return *this;
 
 // (2) 释放原有的内存资源 // 3 分
 delete [] m_data;
 
 // (3)分配新的内存资源,并复制内容 // 3 分
 int length = strlen(other.m_data);
 m_data = new char[length+1]; // 若能加 NULL 判断则更好
 strcpy(m_data, other.m_data);

 // (4)返回本对象的引用 // 3 分
 return *this;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值