c++笔试题目
1 编写函数检查给定字符串是否是整数
//把字符串写做整数,包括正负号
#include <iostream>
#include <cassert>
#include <cmath>
#define ZERO 48
#define NINE 57
#define POSITIVE '+'
#define NEGATIVE '-'
using namespace std;
bool IsInt(const char *pString, int nstrLen, int &nResult)
{
assert(NULL != pString);
bool bPNegative = false; //flase代表负数
int nIndex = 0;
nResult = 0;
if (POSITIVE == (*pString))
{
bPNegative = true;
nIndex = 1;
}
if (NEGATIVE == (*pString))
{
bPNegative = false;
nIndex = 1;
}
//若为字符,变成它表示的数字
for (; nIndex < nstrLen; ++nIndex)
{
char cTemp = *(pString + nIndex);
if (cTemp > ZERO && cTemp < NINE)
{
nResult += (cTemp - ZERO) * pow(10.0, (nstrLen - nIndex - 1));
}
else
{
nResult = 0;
return false;
}
}
//使用正负数表示
if (!bPNegative)
{
nResult = 0 - nResult;
}
return true; //函数返回是否为数字,参数返回数字大小
}
int main()
{
char szString[] = "fsa1";
int nResutlt = 0;
if (IsInt(szString, strlen(szString), nResutlt))
{
cout << nResutlt;
}
return 0;
}
2 有2个无序链表LIST 1 LIST2 将2个合并为一个递增的链表
2.1 先将链表变为有序
2.2 递增有序的2个单链表合并成一个递增有序的单链表,不用任何库函数调用
/*
题目描述: 2个递增有序的单链表,请你把它两个合并成一个有序
的单链表,分普通和不能用任何库函数2种方法
*/
/* 说明: 如果采用一般的做法,直接申请新的空间,组成一个新的
单链表,直接进行归并就可以得到整体的有序序列,这个相对比较简单。
如果不能用任何库函数,也就是不能利用malloc分配内存,就是要利用
现有的2个链表,进行元素交换得到最后有序的链表。
*/
#include <iostream>
using namespace std;
/* 单链表节点 */
struct node
{
int value;
node* next;
};
/* 给单链表添加节点 ,每次插入节点都要从头遍历链表,找到最后一个节点,在其后添加,(该程序使用的方法)*/
void insertNode(node* head, int value)
{
node* p = head->next;
if ( p == NULL )
{
p = new node;
p->value = value;
p->next = NULL;
head->next = p;
return;
}//头节点是哨兵,加入第一个节点
//加入其他节点
while ( p->next != NULL )
{
p = p->next;
}
node* tmp = new node;
tmp->value = value;
tmp->next = NULL;
p->next = tmp;
}
/* 给单链表添加节点,不用遍历链表*/
void insertNode(node* head, int n)
{
node* hd=head;
int value;
for(int i=0;i<n;i++)
{
node* p=new node;
cin>>value;
p->value=value;
p->next=NULL;
hd->next=p;
hd=p;
}
}
/* 遍历输出链表节点 */
void print(node* head)
{
node* p = head->next;
while ( p != NULL )
{
cout << p->value << " ";
p = p->next;
}
cout << endl;
}
/* 利用一般的方法进行合并,形成整体递增有序 ,从小到大*/
node* formalMerge(node* headA, node* headB)
{
node* head = new node;
head->next = NULL;
node* p = headA->next;
node* q = headB->next;
if ( p == NULL )
{
return headB;
}
if ( q == NULL )
{
return headA;
}
while ( (p != NULL) && (q != NULL) )
{
if ( p->value == q->value )
{
insertNode(head, p->value);
insertNode(head, q->value);
p = p->next;
q = q->next;
}
else if ( p->value < q->value )
{
insertNode(head, p->value);
p = p->next;
}
else if ( p->value > q->value )
{
insertNode(head, q->value);
q = q->next;
}
}
while ( p != NULL )
{
insertNode(head, p->value);
p = p->next;
}
while ( q != NULL )
{
insertNode(head, q->value);
q = q->next;
}
return head;
}
/* 下面实现不使用任何库函数, 利用交换的方法在原空间实现整体有序。
方法是先确定哪一个链表的第一个节点的值小,把这个链表的头结点作为合并后链表的头结点,然后比较2个有序链表的当前节点的值,如果代表最后合并链表的值小,则不用交换,否则把两个值交换,最后合并链表始终保持两个值中的小值。另一个链表由于交换了一个元素,当前元素可能影响该链表的有序递增,对其进行调整使其保持
递增有序,然后重复上述动作,直到一个链表遍历结束,然后把剩余的链表连接起来就行。*/
/* 调整链表的节点,使其变成递增有序,head是链表头,哨兵节点,p是改变了value的节点,使链表重新有序,由于原链表有序只要找到第一个大于该节点的位置,将其插入,故需要知道该位置前一个节点,位置节点,p节点前一个 */
void chg2sort(node* head, node* &p)
{
if (head->next == NULL ) //没有节点,直接返回
{
return;
}
node* s = head;
while ( s->next != p ) //s指向p的前一个节点
{
s = s->next;
}
//下面的一段找到第一个大于p节点值的节点
node* q =head->next;
node* r =q;
while ( q != NULL )
{
if ( q->value <= p->value )
{
r = q; //r始终指向q的前一个节点
q = q->next;
}
else
{
break;
}
}
//下面调整指针,其实可以统一写出来,为了阅读清晰把q为NULL和非NULL分开写出来
if ( q == NULL )
{
r->next = p;
s->next = p->next;
p->next = NULL;
}
else if ( q != NULL )
{
s->next = p->next;
r->next = p;
p->next = q;
}
//由于链表进行了调换,当前链表指针也需要改变
p = s->next;
}
/* 两个有序链表进行合并 */
node* merge(node* head1, node* head2)
{
node* head; //合并后的头指针
node* p = head1->next;
node* q = head2->next;
//有一个链表为空的情况,直接返回另一个链表
if ( p == NULL )
{
head = head2;
return head;
}
else if ( q == NULL )
{
head = head1;
return head;
}
//两个都不为空,先确定哪个链表作为合并后的链表
if ( (p != NULL) && (q != NULL) )
{
if ( p->value < q->value )
{
head = head1;
}
else
{
head = head2;
}
}
node* p_prior; //始终指向p节点的前一个节点
node* q_prior;
while ( (p != NULL) && (q != NULL) )
{
if ( p ->value < q->value )
{
if ( head == head1 )
{
p_prior = p;
p = p->next;
}
else if ( head == head2 )
{
//进行当前节点值的交换
int tmp = p->value;
p->value = q->value;
q->value = tmp;
chg2sort(head1, p); //交换元素后的调整
q_prior = q;
q = q->next;
}
}
else if ( p->value == q->value )
{
p_prior = p;
p = p->next;
q_prior = q;
q = q->next;
}
else if ( p->value > q->value )
{
if ( head == head1 )
{
int tmp = p->value;
p->value = q->value;
q->value = tmp;
chg2sort(head2, q);
p_prior = p;
p = p->next;
}
else if ( head == head2 )
{
q_prior = q;
q = q->next;
}
}
}
if ( p != NULL )
{
q_prior->next = p;
}
if ( q != NULL )
{
p_prior->next = q;
}
return head;
}
int main()
{
/* 建立有序链表A */
int a[5] = {1, 5, 8, 10, 20};
node* headA = new node;
headA->next = NULL;
for (int i = 0; i < 5; ++i)
{
insertNode(headA, a[i]);
}
print(headA);
/* 建立有序链表B */
int b[3] = {3, 4, 9};
node* headB = new node;
headB->next = NULL;
for (int i = 0; i < 3; ++i)
{
insertNode(headB, b[i]);
}
print(headB);
/* 利用简单合并的方法合并成整体有序 */
node* head = formalMerge(headA, headB);
print(head);
int c[3] = {5, 4, 9};
node* headC = new node;
headC->next = NULL;
for (int i = 0; i < 3; ++i)
{
insertNode(headC, c[i]);
}
print(headC);
//test chg2sort
chg2sort(headC, headC->next);
print(headC);
head = merge(headA, headB);
print(head);
return 0;
}
//////////////////////////
//head != NULL是合并后链表的头节点,item是另外一个链表的元素。在head指向的链表中找要插入的位置(q<item<p)
1 node* insert_node(node *head, node *item)
2 {
3 node *p = head;
4 node *q = NULL; //始终指向p之前的节点
5
6 while(p->data < item->data && p != NULL)
7 {
8 q = p;
9 p = p->next;
10 }
11 if (p == head) //插入到原头节点之前
12 {
13 item->next = p;
14 return item;
15 }
16 //插入到q与p之间之间
17 q->next = item;
18 item->next = p;
19 return head;
20 }
21
22 /* 两个有序链表进行合并 */
23 node* merge(node* head1, node* head2)
24 {
25 node* head; //合并后的头指针
26 node *p;
27 node *nextP; //指向p之后
28
29 if ( head1 == NULL ) //有一个链表为空的情况,直接返回另一个链表
30 {
31 return head2;
32 }
33 else if ( head2 == NULL )
34 {
35 return head1;
36 }
37
38 // 两个链表都不为空
39 if(length(head1) >= length(head2)) //选取较短的链表
40 { //这样进行的插入次数要少些
41 head = head1;
42 p = head2;
43 }
44 else
45 {
46 head = head2;
47 p = head1;
48 }
49
50 while(p != NULL)
51 {
52 nextP = p->next; //保存p的下一个节点
53 head = insert_node(head, p); //把p插入到目标链表中
54 p = nextP; //指向将要插入的下一个节点
55 }
56
57 return head;
58 }
///////////////////////////
递归方法的步骤如下:
(1)比较链表1和链表2的第一个节点数据,由于1 <2,因此把结果链表头节点指向链表1中的第一个节点,即数据1所在的节点。
(2)对剩余的链表1(3->5)和链表2再调用本过程,比较得到结果链表的第二个节点,即2与3比较得到2。此时合并后的链表节点为1->2。
接下来的过程类似(2),如此递归知道两个链表的节点都被加到结果链表中。
1 node * MergeRecursive(node *head1, node *head2)
2 {
3 node *head = NULL;
4
5 if (head1 == NULL)
6 {
7 return head2;
8 }
9 if (head2 == NUL)
10 {
11 return head1;
12 }
13
14 if ( head1->data < head2->data )
15 {
16 head = head1 ;
17 head->next = MergeRecursive(head1->next,head2);
18 }
19 else
20 {
21 head = head2 ;
22 head->next = MergeRecursive(head1,head2->next);
23 }
24
25 return head ;
26 }