c++面试编程题.docx
《c++面试编程题.docx》由会员分享,可在线阅读,更多相关《c++面试编程题.docx(31页珍藏版)》请在冰豆网上搜索。
c++面试编程题
常用经典编程例子
一个链表的结点结构
structNode
{
intdata;
Node*next;
};
typedefstructNodeNode;
(1)已知链表的头结点head,写一个函数把这个链表逆序(Intel)
Node*ReverseList(Node*head)//链表逆序
{
if(head==NULL||head->next==NULL)
returnhead;
Node*p1=head;
Node*p2=p1->next;
Node*p3=p2->next;
p1->next=NULL;
while(p3!
=NULL)
{
p2->next=p1;
p1=p2;
p2=p3;
p3=p3->next;
}
p2->next=p1;
head=p2;
returnhead;
}
(2)已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序。
(保留所有结点,即便大小相同)
Node*Merge(Node*head1,Node*head2)
{
if(head1==NULL)
returnhead2;
if(head2==NULL)
returnhead1;
Node*head=NULL;
Node*p1=NULL;
Node*p2=NULL;
if(head1->datadata)
{
head=head1;
p1=head1->next;
p2=head2;
}
else
{
head=head2;
p2=head2->next;
p1=head1;
}
Node*pcurrent=head;
while(p1!
=NULL&&p2!
=NULL)
{
if(p1->data<=p2->data)
{
pcurrent->next=p1;
pcurrent=p1;
p1=p1->next;
}
else
{
pcurrent->next=p2;
pcurrent=p2;
p2=p2->next;
}
}
if(p1!
=NULL)
pcurrent->next=p1;
if(p2!
=NULL)
pcurrent->next=p2;
returnhead;
}
(3)已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。
(Autodesk)
答案:
Node*MergeRecursive(Node*head1,Node*head2)
{
if(head1==NULL)
returnhead2;
if(head2==NULL)
returnhead1;
Node*head=NULL;
if(head1->datadata)
{
head=head1;
head->next=MergeRecursive(head1->next,head2);
}
else
{
head=head2;
head->next=MergeRecursive(head1,head2->next);
}
returnhead;
写一个函数找出一个整数数组中,第二大的数(microsoft)
答案:
constintMINNUMBER=-32767;
intfind_sec_max(intdata[],intcount)
{
intmaxnumber=data[0];
intsec_max=MINNUMBER;
for(inti=1;i{
if(data[i]>maxnumber)
{
sec_max=maxnumber;
maxnumber=data[i];
}
else
{
if(data[i]>sec_max)
sec_max=data[i];
}
}
returnsec_max;
}
编程实现单链表的插入
Node*InsertNode(Node*Head,intnum)
{
Node*newNode=newNode;
newNode->data=num;
if(!
Head)//此时为空链表
{
newNode->next=NULL;
returnnewNode;
}
Node*p=Head;
Node*q=NULL;//q指向p结点之前的结点
while(p)//此时寻找位置
{
if(p->data{
q=p;
p=p->next;
}
else//此时找到了位置
break;
}
if(p==Head)//插入到头结点之前
{
newNode->next=Head;
Head=newNode;
}
elseif(!
p)//插入到尾结点之后,此时q指向尾结点
{
q->next=newNode;
newNode->next=NULL;
}
else//插入到p结点和q结点之间
{
newNode->next=q->next;
q->next=newNode;
}
returnHead;
}
编程实现双链表删除结点(注意它和单链表删除结点的情况有所不同)
Node*DoubleLink_DelNode(Node*Head,intnum)
{
Node*p=Head;
if(!
p)
returnNULL;
while(p)
{
if(num!
=p->data)
p=p->next;
else
break;
}
if(!
p)//没有找到要删除的结点
returnNULL;
else
{
if(p==Head)//此时删除的是头结点
{
Head=Head->next;
deletep;
}
elseif(p->next)//此时删除的是中间结点
{
p->prev->next=p->next;
p->next->prev=p->prev;
deletep;
}
else//删除的是尾结点
{
p->prev->next=NULL;
deletep;
}
}
returnHead;
}
编程实现双链表的插入
Node*DoubleLink_InsertNode(Node*Head,intnum)
{
Node*newNode=newNode;//初始化产生一个新结点
newNode->data=num;
newNode->prev=NULL;
newNode->next=NULL;
Node*p=Head;
Node*q=NULL;
while(p)
{
if(p->data{
q=p;
p=p->next;
}
else
break;
}
if(p==Head)//此时是在头结点之前进行插入
{
newNode->next=p;
p->prev=newNode;
Head=newNode;
}
elseif(!
p)//在尾结点之后进行插入
{
q->next=newNode;
newNode->prev=q;
}
else//在中间进行插入
{
p->prev->next=newNode;
newNode->prev=p->prev;
newNode->next=p;
p->prev=newNode;
}
returnHead;
}
如何证明一个表是循环链表
link*p,*q;
p=head;
q=p->next;
while(q&&q->next&&p!
=q) //qorq->next==NULL时无环,q==q时有环
{
p=p->next;
q=q->next->next;
}
if(p==q)
cout<<"havering";
else
cout<<"noring";
如何判断一个单链表是有环的?
(注意不能用标志位,最多只能用两个额外指针)
structnode{charval;node*next;}
boolcheck(constnode*head){}//return false:
无环;true:
有环一种O(n)的办法就是(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然):
boolcheck(constnode*head)
{
if(head==NULL) returnfalse;
node*low=head,*fast=head->next;
while(fast!
=NULL&&fast->next!
=NULL)
{
low=low->next;
fast=fast->next->next;
if(low==fast)returntrue;
}
returnfalse;
}
实现队列的出队与入队
//数据入队列
Node*EnQueue(Node*head,Node**tail,intdata)
{
//创建一个新结点
Node*p=newNode;
p->data=data;
p->next=NULL;
if(head==NULL)//此时为空队列
{
head=p;
*tail=p;
}
else
{
(*tail)->next=p;
*tail=p;
}
returnhead;
}
//删除头结点
Node*DeQueue(Node*head)
{
if(!
head)//头结点为空
returnNULL;
else
{
Node*p=head;
head=head->next;
deletep;
}
returnhead;
}
String的具体实现
已知String类定义如下:
classString
{
public:
String(constchar*str=NULL);//通用构造函数
String(constString&another);//拷贝构造函数
~String();//析构函数
String&operater=(constString&rhs);//赋值函数
private:
char*m_data;//用于保存字符串
};
尝试写出类的成员函数实现。
答案:
String:
:
String(constchar*str)
{
if(str==NULL)//strlen在参数为NULL时会抛异常才会有这步判断
{
m_data=newchar[1];
m_data[0]='\0';
}
else
{
m_data=newchar[strlen(str)+1];
strcpy(m_data,str);
}
}
String:
:
String(constString&another)
{
m_data=newchar[strlen(another.m_data)+1];
strcpy(m_data,other.m_data);
}
String&String:
:
operator=(constString&rhs)
{
if(this==&rhs)
return*this;
delete[]m_data;//删除原来的数据,新开一块内存
m_data=newchar[strlen(rhs.m_data)+1];
strcpy(m_data,rhs.m_data);
return*this;
}
String:
:
~String()
{
delete[]m_data;
}
判断字符串是否为回文
boolIsSymmetry(constchar*p)
{
assert(p!
=NULL);
constchar*q=p;
intlen=0;
while(*q++!
='\0')
{
len++;
}
boolbSign=true;
q=p+len-1;
if(0{
for(inti=0;i{
if(*p++!
=*q--){bSign=false;break;};
}
}
if(bSign==true)
{
printf("Yes!
\n");
}
else
{
printf("No!
\n");
}
returnbSign;
}
整数转换成字符串itoa函数的实现
1#include"stdafx.h"
2#include
3usingnamespacestd;
4voiditoaTest(intnum,charstr[])
5{
6intsign=num,i=0,j=0;
7chartemp[11];
8if(sign<0)//判断是否是一个负数
9{
10num=-num;
11};
12do
13{
14temp[i]=num%10+'0';
15num/=10;
16i++;
17}while(num>0);
18if(sign<0)
19{
20temp[i++]='-';
21}
22temp[i]='\0';
23i--;
24while(i>=0)
25{
26str[j]=temp[i];
27j++;
28i--;
29}
30str[j]='\0';
31}
编程实现字符串转化为整型,不用atoi
32stringstr;
33intsum=0;
34cin>>str;
35for(inti=0;i36{
37sum=sum*10+str[i]-'0';
38}
39cout<请写出一个函数来模拟c++中的strstr函数:
该函数的返回值是主传中字符子串的位置以后的所有字符,请不要使用任何c程序已有的函数
40stringLeftSting(conststring&Srcstr,conststring&Substr)
41{
42stringResults("");
43inti=0;
44while(i45{
46intj=i;
47intk=0;
48while(k49{
50if(Srcstr[j]==Substr[k])
51{
52j++;
53k++;
54}
55else
56break;
57}
58if(k==Substr.size())//找到了子串
59{
60for(intt=i;t61Results+=Srcstr[t];
62break;
63}
64elseif(k==0)//此时第一个不是匹配的
65i++;
66else//此时已经匹配了k个字符
67i+=k;
68}
69returnResults;
70}
字符串输出
35.22.简单应用题
请编写一个函数display(),该函数要求用户先输入一字符串,然后在屏幕上再输出该字符串(假设该字符串长度小于100)。
注意:
部分源程序已存在文件test35_2.cpp中。
请勿修改主函数main和其他函数中的任何内容,仅在函数display()的花括号中填写若干语句。
如输入abc,输出结果如下:
pleaseinputstring:
abc
abc
Pressanykeytocontinue
文件test35_2.cpp的内容如下:
#include
#include
voiddisplay()
{
}
voidmain()
{
cout<<"pleaseinputstring:
"<display();
}
【答案】
voiddisplay()
{
charstr[100],ch;
inti=0;
while((ch=getche())!
='\r')
{
str[i]=ch;
i++;
}
str[i]='\0';
cout<}
2.2字符串翻转
16.22.简单应用题
请编写一个函数voidfun(charss[]),该函数将字符串ss翻转,如ss为"123abc"则翻转后为"cba321"。
注意:
用数组方式及for循环来实现该函数。
注意:
部分源程序已存在文件test16_2.cpp中。
请勿修改主函数main和其他函数中的任何内容,仅在函数fun的花括号中填写若干语句。
文件test16_2.cpp的内容如下:
#include
#include
voidfun(charss[]);
voidmain()
{
chars[80];
cout<<"请输入字符串:
";
cin>>s;
fun(s);
cout<<"逆序后的字符串:
"<
}
voidfun(charss[])
{
}
【答案】voidfun(charss[])
{
intn=strlen(ss);
for(inti=0;i<(n/2);i++)
{
charc=ss[i];
ss[i]=ss[n-1-i];
ss[n-1-i]=c;
}
}
2.3字符串大小写转换
21.22.简单应用题
请编写一个函数char*change(charinstr[]),将输入字符串中的所有小写字母转换为大写字母输出。
要求使用for循环实现。
如输入jinfeiteng,则输出结果是JINFEITENG。
注意:
部分源程序已存在文件test21_2.cpp中。
请勿修改主函数main和其他函数中的任何内容,仅在函数change的花括号中填写若干语句。
文件test21_2.cpp的内容如下:
char*change(charinstr[]);
#include"iostream.h"
voidmain()
{
charinstr[50];
char*outstr;
cout<<"Inputastring:
"<cin>>instr;
outstr=change(instr);
cout<<"Overgradedstring:
"<cout<}
char*change(charinstr[])
{
}
【答案】
char*change(charinstr[])
{
char*outstr=newchar[50];
constchardelta='A'-'a';
inti;
for(i=0;instr[i]!
='\0';i++)
{
if(instr[i]>='a'&&instr[i]<='z')
{
outstr[i]=instr[i]+delta;
}
else
{
outstr[i]=instr[i];
}
}
outstr[i]='\0';
returnoutstr;
}
2.4字符串连接
4.22.简单应用题
常用字符串函数strcat(s1,s2)可将字符串s2添加到字符串s1的末端,但其使用必须保证字符串s1足够大,以便保存它自己的内容和字符串s2中的内容。
请编写一个函数char*append(char*s1,char*s2),其可将字符串s2添加到字符串s1的末端,而且不受s1空间大小的限制。
请利用常用字符串函数实现。
常用字符串函数说明:
strcpy(to,form):
将form字符串复制到to字符串;
strcat(s1,s2):
将字符串s2添加到字符串s1的末端,但必须保证字符串s1足够大;
strlen(s):
返回字符串s的长度;
注意:
部分源程序已存在文件test4_2.cpp中。
请勿修改主函数main和其他函数中的任何内容,仅在函数append的花括号中填写若干语句。
输出结果如下:
thisisastring.
文件test4_2.cpp的内容如下:
#include
#include
char*append(char*s1,char*s2)
{
}
voidmain()
{
char*s,*s1,*s2;
s1="thisis";
s2="astring.";
s=append