您的位置:首页 > 编程语言 > C语言/C++

C++面试基础之手写代码

2014-07-02 20:58 351 查看
今天总结了一些关于计算机专业面试测试常会被面试官拿来现场考我们的编程能力(就是手写代码咯)的题,附上了源代码,所有程序都已经经过测试通过,也讲解一些注意点。希望对大家有用。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

1、用宏定义比较两个参数的大小函数,参数为A、B。

标准答案:

#define MIN(A,B) ((A) <= (B) ? (A) : (B))


注:a)三组括号,少一个0分

        b)结尾有分号,0分

 2、计算1+2+……n的值

标准答案:

int Sum( int n )
{
 return ( (long)1 + n) * n / 2;  //或return (1l + n) * n / 2;
}


注:a)1前面的long没有写,0分;考察的是当n很大时,可能有数位溢出

        b)这是最简洁的,其他的写法有,可以自行解决

3、计算n!

标准答案:

递归算法:

int Factorial(int n)
{
if (n>=0)
{
if(0==n||1==n)
return 1;
else
return Factorial(n-1)*n;
}
else
return -1;
}


非递归算法:

int Factorial(int n)
{
static int res=1;
if (n>=0)
{
if (0==n||1==n)
return 1;
else
{
for (int i=1;i<n+1;i++)
res *=i;
return res;
}
}
else
return -1;
}


4、计算斐波那契数(输出整个数列可以适当修改,大同小异)

标准答案:

递归算法:

int Fibonacci(int n)
{
if (n>=1)
{
if (n==1||n==2)
return 1;
else
return (Fibonacci(n-1)+Fibonacci(n-2));
}
else
return -1;
}


非递归算法:

int Fibonacci(int n)
{
if (n>=1)
{
if (n==1||n==2)
return 1;
else
{
int temp,f1 = 1,f2 = 1;
while((n--)>2)
{
temp = f1+f2;
f1 = f2;
f2 = temp;
}
return temp;
}
}
else
return -1;
}


5、求水仙花数

这里也就不求了,它的核心就是求一个数的每一位上的数字。下面列举基本求法,举一反三。

对于数56789,每个数位上的数字为:(python写的)

>>> int(56789/10000)
5
>>> int(56789/1000%10)
6
>>> int(56789/100%10)
7
>>> int(56789/10%10)
8
>>> int(56789%10)


6、求某一范围内的素数

标准答案:

int  Prime(int l,int r)
{
if (l<=r&&l>0)
{
for (int i = l;i<r+1;i++)
{
if(i==1||i==2||i==3)
cout<<i<<endl;
else
{
for (int j =2;j<ceil(i/2.0);j++ )
{
if((i%j)==0)
break;
else
if(j==(ceil(i/2.0)-1))
cout<<i<<endl;
}
}
}
}
else
return -1;
}

注:a)注意ceil函数的应用以及(i/2.0)的原因

        b)题目的满足条件的划分,所以本函数的核心就是else那块,其余的都是次要的划分

7、合数的质因素分解,如90=2*3*3*5

标准答案:

void NumDecomposition(int n)
{
for (int i=2;i<n+1;i++)
{
while (i!=n)//可能重复的质数
{
if (n%i==0)
{
cout<<i<<"*";
n = int(n/i);
}
else
break;
}
if (i==n)//最后一个质数输出
cout<<i;
}
}


8、输入一个整数,输出其二进制表示中1的个数。

标准答案:

int func (x)
{
int countx = 0;
while ( x )
{
countx ++;
x = x&(x-1);
}
return countx;
}
注:本题的核心就是x&(x-1)的位运算,为什么可以呢?

9、字符大小写的转换(字符串的的大小写转换可以基于此)

标准答案:

法一:

char Trans(char &ch)//大写转小写
{
return  ((ch>'A'&&ch<'Z')?ch+32:ch);
}


注:这里的核心就是ch+32的理解。另外,这里没有对ch的合法性进行检查,可以补上。

法二:

调用库函数:tolower('A') 、toupper('A')


法三:

boost里的整个字符串的转换:

#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;

wstring wstr =L"Abc";
boost::to_lower(wstr); // abc
注:很多面试的题像这样简单,但是他考察的是我们的知识广度,STL会么?boost会么?库函数会不会用?都是考察的要点。

10、对于电脑存储大小端的判定

标准答案:

int checkCPUendian()
{//大端则输出1,小端则输出0
union
{
int a;
char c;
}MyUnion;
MyUnion.a =0x0134;
return (MyUnion.c==1);
}
注:这里应用的要点就是union的性质:struct每个成员分别占有其自己的内存单元,而union共用体变量所占的内存长度等于最长的成员的长度。

11、题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。

标准答案:

void func1()
{
for (int i = 'x';i<'z'+1;i++)
{
for (int j = 'x';j<'z'+1;j++)
{
if (i!=j)
{
for (int k = 'x';k<'z'+1;k++)
{
if (j!=k)
{
if ((i!='x')&&(k!='x')&&(k!='z'))
{
cout<<'a'<<"--"<<(char)i<<" "
<<'b'<<"--"<<(char)j<<" "
<<'c'<<"--"<<(char)k<<" "<<endl;
}
}
}
}
}
}
}
注:本题的核心就是三层循环,写得有些复杂,其实可以简化。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

assert()

头文件:#include <assert.h>

ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:……

  ASSERT( n != 0);k = 10/ n;……

  ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。

  assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。

12、strcpy

原型声明:extern char *strcpy(char* dest, const char *src); 

功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间

说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

返回指向dest的指针。

#include <assert.h>
char* strcpy1(char* dest, const char* scr)
{
assert((dest!=NULL)&&(scr!=NULL));
char* address = dest;
while ((*dest++=*scr++)!='\0');
return address;
}

测试:
char a[]="hello";
char b[]="123";
cout<<strcpy1(b,a);


另:解释为什么要返回char *?

返回strDest的原始值使函数能够支持链式表达式,增加了函数的“附加值”。同样功能的函数,如果能合理地

提高的可用性,自然就更加理想。 

链式表达式的形式如: 

  int iLength=strlen(strcpy(strA,strB)); 

13、strlen 

原型:extern unsigned int strlen(char *s);

功能:计算字符串s的(unsigned int型)长度,不包括'\0'在内

说明:返回s的长度,不包括结束符NULL。

int strlen1(const char* dest)
{
assert(dest!=NULL);
int len=0;
while (*dest++!='\0')
len ++;
return len;
}

测试:
char a[]="hello";
cout<<strlen1(a);


14、strcmp

原型:extern int strcmp(const char *s1,const char * s2);

功能:比较字符串s1和s2。

一般形式:strcmp(字符串1,字符串2)

说明

当s1<s2时,返回为负数

当s1=s2时,返回值= 0

当s1>s2时,返回正数

即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。如:

返回值:返回整数值,如果dest > source,则返回值大于0,如果dest = source,则返回值等于0,如果dest < source ,则返回值小于0。字符大小是按照字符的字典序列进行排列的。

int strcmp1(const char *dest, const char *source)
{
assert((NULL != dest) && (NULL != source));
while (*dest && *source && (*dest == *source))
{
dest ++;
source ++;
}
return *dest - *source;
}


15、strcat

原型:extern char *strcat(char *dest,char *src);

功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。

说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

返回指向dest的指针。

char *strcat1(char *strDest, const char *strScr) //将源字符串加const,表明其为输入参数
{
assert((strDest != NULL) && (strScr != NULL)); //对源地址和目的地址加非0断言
char * address = strDest;
while(*strDest*strDest!=’/0’)             //是while(*strDest!=’/0’)的简化形式
strDest++;               //约束的。所以要在循环体内++;因为要是*strDest最后指
while((*strDest++ = *strScr++) !='\0');//是while((*strDest++ = *strScr++)!=’/0’)的简化形式
return address;               //为了实现链式操作,将目的地址返回
}


16、strstr

函数原型:extern char *strstr(const char *str1, const char *str2);

语法:* strstr(str1,str2)

str1: 被查找目标 string expression to search.

str2: 要查找对象 The string expression to find.

返回值:该函数返回str2第一次在str1中的位置,如果没有找到,返回NULL

例子:

charstr[]="1234xyz";

char*str1=strstr(str,"34");

cout<<str1<<endl;

显示: 34xyz

const char* StrStr1(const char *str1, const char *str2)
{
assert(NULL != str1 && NULL != str2);
while(*str1 != '\0')
{
const char *p = str1;
const char *q = str2;
const char *res = NULL;
if(*p == *q)
{
res = p;
while(*p && *q && *p++ == *q++);
if(*q == '\0')
return res;
}
str1++;
}
return NULL;
}


17、strpbrk

功能:依次检验字符串s1中的字符,当被检验字符在字符串s2中也包含时,则停止检验,并返回该字符位置,空字符NULL不包括在内。

说明:返回s1中第一个满足条件的字符的指针,如果没有匹配字符则返回空指针NULL。

用途:在源字符串(s1)中找出最先含有搜索字符串(s2)中任一字符的位置并返回,若找不到则返回空指针。

原型:extern char *strpbrk(const char *s1, const char *s2);

char *strpbrk(const char *strSrc, const char *str)
{
assert((strSrc != NULL) && (str != NULL));
const char *s;
while (*strSrc != '/0')
{
s = str;
while (*s != '/0')
{
if (*strSrc == *s)
return (char *) strSrc;
++ s;
}
++ strSrc;
}
return NULL;
}


18、strchr

原型:extern char *strchr(const char *s,char c);查找字符串s中首次出现字符c的位置

功能:查找字符串s中首次出现字符c的位置

说明:返回首次出现c的位置的指针,返回的地址是字符串在内存中随机分配的地址再加上你所搜索的字符在字符串位置,如果s中不存在c则返回NULL。

返回值:成功则返回要查找字符第一次出现的位置,失败返回NULL

char *strchr1(const char *str, char c)
{
assert(str != NULL);
while (*str!=c&&*str!='\0')
++str;
return *str ==c?(char*)str:NULL;

/*另解:
for (; *str != (char)c; ++ str)
if (*str == '/0')
return NULL;
return (char*)str;   */
}


19、strset

原型:extern char *strset(char *s, char c);

用法:#include <string.h>

功能:把字符串s中的所有字符都设置成字符c。

说明:返回指向s的指针。

特别注意:strset(s,c); 把字符串s中的所有字符都设置成字符c,但是s本身尚未赋值,也就是说没有字符串结束标志'\0',但是该函数执行时将直到发现'\0'才停止,这就会出现问题,干涉到其他变量(并有不可知性),一般情况下紧邻定义的变量在内存中也是连续的,很容易受到影响。

char *strset(char *str, int c)
{
assert(str != NULL);
char *s = str;
for (; *s != '\0'; ++ s)
*s = (char) c;
return str;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

未完待续……

参考文献:

http://blog.csdn.net/v_july_v/article/details/6417600
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息