C/C++笔试题(编程题)

时间:2023-03-08 16:46:21

面试过程中遇到的编程题整理,于此备录。分享,共勉。(持续更新中......欢迎补充)

(1)用户输入M, N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。

程序代码如下:

 #include <stdio.h>
#include <stdlib.h> // 节点结构定义
typedef struct Link_Node
{
int data;
Link_Node* next;
}Node, *pNode; // 创建循环链表
void CreateList(pNode& head, pNode& tail, int n)
{
if (n < )
{
head = NULL;
return;
} head = (pNode)malloc(sizeof(Node));
head->data = ;
head->next = NULL; pNode p = head;
for (int i = ; i < n+; ++i)
{
p->next = (pNode)malloc(sizeof(Node));
p = p->next;
p->data = i;
p->next = NULL;
} tail = p;
p->next = head;
} // 打印循环链表
void Print(pNode& head)
{
pNode p = head;
while (p != NULL && p->next != head)
{
printf("%d ", p->data);
p = p->next;
}
if (p != NULL)
{
printf("%d\n", p->data);
}
} // 用户输入M, N值,从1至N开始顺序循环数数,每数到M输出该数值。
// 直至全部输出
void LoopPrint(pNode& head, pNode& tail, int m)
{
pNode pPre = tail, pCur = head; int nCount = m - ;
while (pCur != NULL && pCur != pCur->next)
{
if (nCount > )
{
nCount--;
pPre = pCur;
pCur = pCur->next;
}
else
{
pPre->next = pCur->next;
printf("%d ", pCur->data);
free(pCur); pCur = pPre->next;
nCount = m - ;
}
} if (pCur != NULL)
{
printf("%d ", pCur->data);
free(pCur); head = tail = NULL;
} printf("\n");
} void main()
{
pNode head = NULL, tail = NULL;
int m = , n = ;
printf("请输入m,n的值:\n");
scanf("%d", &m);
scanf("%d", &n);
// 创建循环链表
CreateList(head, tail, n);
// 打印链表
printf("打印链表数据信息如下:\n");
Print(head);
printf("\n");
// 循环输出
printf("循环数数,遇到M输出结果如下:\n");
LoopPrint(head, tail, m);
system("pause");
}
// run out:
/*
请输入m,n的值:
2
10
打印链表数据信息如下:
1 2 3 4 5 6 7 8 9 10 循环数数,遇到M输出结果如下:
2 4 6 8 10 3 7 1 9 5
请按任意键继续. . .
*/

(2)从键盘输入10个学生的学号和成绩,按成绩从大到小建立一个有序链表,并输出。

程序代码如下:

 #include <stdio.h>
#include <stdlib.h> typedef struct node
{
int xh;
int cj;
struct node *next;
}Node, *pNode; void main()
{
pNode head = NULL, s, p, pre; int i = ;
while (i++ < )
{
s = (pNode)malloc(sizeof(Node));
s->next = NULL;
printf("第%d个学生(学号 成绩):", i);
scanf("%d%d", &s->xh, &s->cj);
if (head == NULL)
{
head = s; // 第一个学生
}
else
{
p = head;
pre = p;
while ((p != NULL) && (s->cj < p->cj))
{
pre = p;
p = p->next;
}
if (p == head)
{
s->next = head;
head = s;
}
else if (p == NULL)
{
pre->next = s;
}
else
{
s->next = pre->next;
pre->next = s;
}
}
} printf("\n 输出结果: \n");
p = head;
while (p != NULL)
{
printf("(%d)-->%d \n", p->xh, p->cj);
p = p->next;
} system("pause");
}
// run out:
/*
第1个学生(学号 成绩):1 69
第2个学生(学号 成绩):2 89
第3个学生(学号 成绩):3 59
第4个学生(学号 成绩):4 100
第5个学生(学号 成绩):5 68
第6个学生(学号 成绩):6 85
第7个学生(学号 成绩):7 82
第8个学生(学号 成绩):8 91
第9个学生(学号 成绩):9 72
第10个学生(学号 成绩):10 80 输出结果:
(4)-->100
(8)-->91
(2)-->89
(6)-->85
(7)-->82
(10)-->80
(9)-->72
(1)-->69
(5)-->68
(3)-->59
请按任意键继续. . .
*/

(3)利用无序数组元素构建一个有序单链表。

 #include <stdio.h>
#include <stdlib.h> typedef struct node
{
int data;
struct node *next;
}Node, *pNode; void main()
{
pNode head = NULL, s, p, pre;
// 构建有序链表
int nArray[] = {, , , , , , , , , };
for (int i = ; i < ; ++i)
{
s = (pNode)malloc(sizeof(Node));
s->data = nArray[i];
s->next = NULL; if (head == NULL)
{
head = s;
}
else
{
p = head;
pre = p;
while ((p != NULL) && (s->data < p->data))
{
pre = p;
p = p->next;
} if (p == head)
{
s->next = head;
head = s;
}
else if (p == NULL)
{
pre->next = s;
}
else
{
s->next = pre->next;
pre->next = s;
}
}
} printf("输出结果: \n");
p = head;
while (p != NULL)
{
printf("%d \n", p->data);
p = p->next;
} system("pause");
}
// run out
/*
输出结果:
100
90
89
65
45
45
32
23
12
7
请按任意键继续. . .
*/

(4)写一个函数找出一个整数数组中,第二大的数 (microsoft)

程序代码如下:

 #include <iostream>
using namespace std; const int MINNUMBER = -; int find_sec_max(int data[], int count)
{
int maxnumber = data[];
int sec_max = MINNUMBER;
for (int i = ; i < count; i++)
{
if (data[i] > maxnumber)
{
sec_max = maxnumber;
maxnumber = data[i];
}
else
{
if (data[i] > sec_max)
sec_max = data[i];
}
} return sec_max;
} void main()
{
int nArray[] = {, , , , , , , , , };
cout << find_sec_max(nArray, ) << endl;
system("pause");
}
// run out:
/*
990
请按任意键继续. . .
*/

(5)求整型数组中的最小以及次小项。

参见随笔《面试题(1)-->【7】

(6)如何判断一个单链表是有环的?(注意不能用标志位,最多只能用两个额外指针)

程序代码如下:

 // 方法1:
bool checkLoop(node * head)
{
if (NULL == head)
return false; node *low = head;
node *fast = head->next;
while (fast != NULL && fast->next != NULL)
{
low = low->next;
fast = fast->next->next;
if (low == fast)
return true;
} return false;
} // 方法2:
bool IsLoop(node *head)
{
if (NULL == head || NULL == head->next)
{
return false;
} node *p1 = head;
node *p2 = head;
do
{
p1 = p1->next;
p2 = p2->next->next;
} while (p2 && p2->next && p1 != p2); return (p1 == p2);
}

(7)字符串功能函数

参见随笔《字符串strcpy

参见随笔《字符串strlen

参见随笔《字符串strcat

参见随笔《字符串strcmp

参见随笔《字符串memcpy

(8)字符串函数集合

1、字符数组的环形移动如何实现?

2、如何判断一个字符串是否是回文串?

3、如何把数字字符串转换为整型数据?

4、如何把整型数据转换为字符串?

5、如何对字符串进行排序?

6、如何把字符串中某个指定的字符删除?

7、如何找出01字符串中0与1出现的最大次数?

8、如何从字符串的某一个位置删除指定个数的字符?

9、写一个函数把字符串反转

10、写一个函数查找两个字符串中的第一个公共字符串

11、写一个函数在字符串N中查找第一次出现子串M的位置。

12、写一个函数把字符串A中的B字符子串用字符串C进行替换。

(9)c语言 文件读写代码

 #include <stdio.h>
#include <stdlib.h> void main()
{
FILE *fp;
char ch, filename[];
scanf("%s", filename);
if ((fp = fopen(filename, "w")) == NULL)
{
printf("cann't open file\n");
exit();
}
ch = getchar();
while (ch != '#')
{
fputc(ch, fp);
putchar(ch);
ch = getchar();
} fclose(fp);
system("pause");
}

(10)memcpy内存拷贝函数

参见随笔《字符串memcpy

(11)判断大小端模式。

程序代码如下:

 #include <iostream>
using namespace std; int CheckCpu()
{
union w
{
int a;
char b;
}c;
c.a = ;
return (c.b == );
} void main()
{
cout << CheckCpu() << endl; // 1 //说明是小端模式
system("pause");
}

大小端模式分析:

嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。

采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节。而Big-endian模式对操作数的存放方式是从高字节到低字节。

例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址 存放内容

0x4000 0x34

0x4001 0x12

而在Big-endian模式CPU内存中的存放方式则为:

内存地址 存放内容

0x4000    0x12

0x4001    0x34

32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址 存放内容

0x4000    0x78

0x4001    0x56

0x4002    0x34

0x4003    0x12

而在Big-endian模式CPU内存中的存放方式则为:

内存地址 存放内容

0x4000    0x12

0x4001    0x34

0x4002    0x56

0x4003    0x78

联合体union的存放顺序是所有成员都从低地址开始存放,面试者的解答利用该特性,轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。

(12)写一个宏,求结构体中成员变量的偏移量。

 #include<iostream>
#include<cstddef>
using namespace std; #define offset(s, a) ((int)(&(((s *)0)->a))) struct s
{
int a;
char d;
int b;
char c;
}; void main()
{
cout << offset(s, a) << endl; //
cout << offset(s, b) << endl; //
cout << offset(s, c) << endl; //
cout << offset(s, d) << endl; //
system("pause");
}
// run out:
/*
0
8
12
4
请按任意键继续. . .
*/

解析图如下:

C/C++笔试题(编程题)

(13)用户输入两个整数,求最大公约数和最大公倍数。

程序代码如下:

 #include <iostream>
using namespace std; void main()
{
int max_divisor, min_multiple;
int n1, n2, m, n;
cout << "输入整数 n1 = ";
cin >> n1;
cout << "输入整数 n2 = ";
cin >> n2;
if (n1 < n2)
{
swap(n1, n2);
}
max_divisor = n1;
n = n2;
while (n != )
{
m = max_divisor % n;
max_divisor = n;
n = m;
}
min_multiple = n1 * n2 / max_divisor;
cout << "最大的公约数是: " << max_divisor << endl;
cout << "最小的公倍数是: " << min_multiple << endl;
system("pause");
}
// run out:
/*
输入整数 n1 = 6
输入整数 n2 = 3
最大的公约数是: 3
最小的公倍数是: 6
请按任意键继续. . .
*/

(14)单链表

1、创建有序单链表

2、向有序链表添加一个新节点

3、求链表的中间节点

4、逆置链表

5、判断是否有环

程序代码如下:

 #include <stdio.h>
#include <stdlib.h> typedef struct node
{
int data;
struct node *next;
}Node, *pNode; // 打印链表数据
void PrintList(pNode head)
{
if (NULL == head || NULL == head->next)
return; pNode p = head->next;
while (p != NULL)
{
printf("%d \n", p->data);
p = p->next;
}
} // 查找链表的中间节点
Node* FindMiddleNode(pNode head)
{
int i = , j = ;
pNode current = NULL;
pNode middle = NULL;
current = middle = head->next;
while (current != NULL)
{
if (i/ > j)
{
++j;
middle = middle->next;
}
++i;
current = current->next;
} return middle;
} void CreateList(pNode& head, int nValue)
{
pNode s, p, pre;
s = (pNode)malloc(sizeof(Node));
s->data = nValue;
s->next = NULL; if (NULL == head)
{
head = s;
}
else
{
p = head;
pre = p;
while ((p != NULL) && (s->data < p->data))
{
pre = p;
p = p->next;
} if (p == head)
{
s->next = head;
head = s;
}
else if (NULL == p)
{
pre->next = s;
}
else
{
s->next = pre->next;
pre->next = s;
}
}
} pNode Reverse(pNode head)
{
pNode p = NULL, q = NULL;
if (NULL == head || head->next == NULL)
{
return head;
} p = head->next;
q = p->next;
p->next = NULL;
while (q != NULL)
{
p = q;
q = q->next;
p->next = head->next;
head->next = p;
} return head;
} // 逆置无头节点的单链表
/*
pNode Reverse(pNode firstNode)
{
pNode p = NULL, q = NULL;
if (NULL == firstNode || firstNode->next == NULL)
{
return firstNode;
} p = firstNode;
q = p->next;
p->next = NULL;
while (q != NULL)
{
p = q;
q = q->next;
p->next = firstNode;
firstNode = p;
} return firstNode;
}
*/ bool IsLoop(pNode headNode)
{
pNode p1 = headNode;
pNode p2 = headNode;
if (NULL == headNode || headNode->next == NULL)
{
return false;
}
do
{
p1 = p1->next;
p2 = p2->next->next;
} while(p2 && p2->next && p1 != p2); return (p1 == p2);
} // 有序链表插入节点
pNode Insert_node(pNode head, int nValue)
{
pNode item = (pNode)malloc(sizeof(Node));
item->data = nValue;
item->next = NULL; if (NULL == head->next)
{
head->next = item;
return head;
} Node *p = head->next;
Node *q = NULL;
while (p != NULL && (p->data > item->data))
{
q = p;
p = p->next;
} if (p == head->next)
{
item->next = p;
head->next = item;
return head;
} q->next = item;
item->next = p;
return head;
} void main()
{
// 构建有头节点的有序链表
pNode headNode = (pNode)malloc(sizeof(Node));
headNode->data = -;
headNode->next = NULL; int nArray[] = {, , , , , , , , , };
for (int i = ; i < ; ++i)
{
CreateList(headNode->next, nArray[i]);
} printf("有序链表(由大到小)输出结果: \n");
PrintList(headNode); headNode = Insert_node(headNode, ); // 最前面插入
headNode = Insert_node(headNode, ); // 中间插入
headNode = Insert_node(headNode, ); // 末尾插入 printf("有序链表(由大到小)输出结果: \n");
PrintList(headNode); pNode midNode = FindMiddleNode(headNode);
if (midNode != NULL)
{
printf("中间节点的数据值: %d \n", midNode->data);
} pNode head = Reverse(headNode);
if (head != NULL)
{
printf("逆置后输出结果: \n");
PrintList(head);
} printf("是否有环? %d \n", IsLoop(headNode));
system("pause");
}
// run out
/*
有序链表(由大到小)输出结果:
100
90
89
65
45
45
32
23
12
7
有序链表(由大到小)输出结果:
110
100
90
89
65
45
45
32
30
23
12
7
5
中间节点的数据值: 45
逆置后输出结果:
5
7
12
23
30
32
45
45
65
89
90
100
110
是否有环? 0
请按任意键继续. . .
*/

(15)字符串长度函数strlen

参见随笔《字符串(strlen) 》

(16)排序集

1、冒泡排序

2、选择排序

3、插入排序

4、快速排序

5、希尔排序

6、堆排序

7、归并排序

8、桶排序

9、基数排序

(17)写一个函数返回1 + 2 + 3 +…+ n的值(假定结果不会超过长整型变量的范围)

程度代码如下:

 #include <stdio.h>
#include <stdlib.h> int Sum(int n)
{
return ((long) + n) * n / ;
} void main()
{
printf("%d\n", Sum()); //
system("pause");
}

(18)合并有序链表,并且合并后仍然为有序链表

程序代码如下:

 #include <stdio.h>
#include <stdlib.h> typedef struct node
{
int data;
struct node *next;
}Node, *pNode; // 创建链表
void CreateList(pNode& head, int nValue)
{
pNode s, p, pre;
s = (pNode)malloc(sizeof(Node));
s->data = nValue;
s->next = NULL; if (NULL == head)
{
head = s;
}
else
{
p = head;
pre = p;
while ((p != NULL) && (s->data > p->data))
{
pre = p;
p = p->next;
} if (p == head)
{
s->next = head;
head = s;
}
else if (NULL == p)
{
pre->next = s;
}
else
{
s->next = pre->next;
pre->next = s;
}
}
} // 合并有序链表
pNode Merge(pNode head1, pNode head2)
{
if (NULL == head1)
return head2;
if (NULL == head2)
return head1; pNode head = NULL;
pNode p1 = NULL;
pNode p2 = NULL;
if (head1->data < head2->data)
{
head = head1;
p1 = head1->next;
p2 = head2;
}
else
{
head = head2;
p2 = head2->next;
p1 = head1;
}
pNode 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; return head;
} // 递归合并有序链表
pNode MergeRecursive(pNode head1, pNode head2)
{
if (NULL == head1)
return head2; if (NULL == head2)
return head1; pNode head = NULL ;
if (head1->data < head2->data )
{
head = head1 ;
head->next = MergeRecursive(head1->next, head2);
}
else
{
head = head2;
head->next = MergeRecursive(head1, head2->next);
} return head ;
}
// 打印无头结点的链表数据
void PrintListHead(pNode head)
{
if (NULL == head)
return; pNode p = head;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
} // 构建有序链表
void create(pNode& headNode)
{
for (int i = ; i < ; ++i)
{
CreateList(headNode, rand() % );
} PrintListHead(headNode);
printf("\n");
} void main()
{
// 构建有序链表1
pNode headNode1 = NULL, headNode2 = NULL;
pNode headNode3 = NULL, headNode4 = NULL; printf("打印有序链表1:\n");
create(headNode1); printf("打印有序链表2:\n");
create(headNode2); printf("打印有序链表3:\n");
create(headNode3); printf("打印有序链表4:\n");
create(headNode4); pNode newHead1 = Merge(headNode1, headNode2);
pNode newHead2 = MergeRecursive(headNode3, headNode4);
printf("打印合并有序链表(1、2):\n");
PrintListHead(newHead1);
printf("打印合并有序链表(3、4):\n");
PrintListHead(newHead2); system("pause");
}
// run out:
/*
打印有序链表1:
41 64 67 78 100 124 134 158 162 169 打印有序链表2:
27 27 36 81 91 105 142 145 161 195 打印有序链表3:
4 21 92 95 102 116 118 153 182 191 打印有序链表4:
35 47 67 69 94 99 112 126 138 171 打印合并有序链表(1、2):
27 27 36 41 64 67 78 81 91 100 105 124 134 142 145 158 161 162 169 195
打印合并有序链表(3、4):
4 21 35 47 67 69 92 94 95 99 102 112 116 118 126 138 153 171 182 191
请按任意键继续. . .
*/

(19)assert宏的实现

程序代码如下:

 void _assert(const char *p, const char *f, int n)
{
cout << p << endl;
cout << f << endl;
cout << n << endl;
}
#define assert(e)\
((e) ? (void) : _assert(#e, __FILE__, __LINE__))

(20)实现全排列函数。

程序代码如下:

 #include<iostream>
using namespace std; template<class Type>
void Perm(Type list[], int k, int m)
{
static int nCount = ;
if (k == m)
{
cout << ++nCount << ": ";
for (int i = ; i <= m; i++)
cout << list[i]; cout << endl;
}
else
{
for (int i = k; i <= m; i++)
{
Swap(list[k], list[i]);
Perm(list, k + , m);
Swap(list[k], list[i]);
}
}
} template <class Type>
inline void Swap(Type &a, Type &b)
{
Type temp = a; a = b; b = temp;
} void main()
{
int ar[] = {, , , , };
Perm(ar, , ); system("pause");
}
// run out:
/*
1: 12345
2: 12354
3: 12435
4: 12453
5: 12543
6: 12534
7: 13245
8: 13254
9: 13425
10: 13452
11: 13542
12: 13524
13: 14325
14: 14352
15: 14235
16: 14253
17: 14523
18: 14532
19: 15342
20: 15324
21: 15432
22: 15423
23: 15243
24: 15234
请按任意键继续. . .
*/

(21)将一个数值由N进制转换为M进制。

程序代码如下:

 #include <iostream>
#include <queue>
#include <stack>
#include <cstring>
using namespace std; //幂函数的小递归 不解释
int npow(int value, int pow)
{
int res = ;
if (pow > )
{
res = value * npow(value, pow - );
return res;
}
else
return ;
} // N进制转换为M进制
char* ntom(int n, int m, char *data, char *res_str)
{
queue<int> iq;
stack<int> is; int len = strlen(data);
//处理输入data中的字符 也就是10进制以上的进制中出现的ABCD…
while (len > )
{
if (data[len - ] >= 'A' && data[len - ] <= 'F')
data[len - ] = + (data[len - ] - 'A') + '';
iq.push(data[len - ] - '');
len--;
}
//将data转为10进制 并保存在val1中 val1是个中间值
int q_size = iq.size();
int val1 = ;
for (int ix = ;ix < q_size; ix++)
{
val1 += iq.front() * npow(n, ix);
iq.pop();
}
//将10进制数val1转为M进制 并依次压栈
int tmp2;
while (val1 > )
{
tmp2 = val1%m;
is.push(tmp2);
val1 = val1 / m;
} int j = ;
char res[];
//转换后的数如果存在ABCD…则处理 否则直接转为字符 并保存于res中
while (!is.empty())
{
if (is.top() >= )
{
res[j] = 'A' + (is.top() - );
}
else
{
res[j] = is.top() + '';
}
j++;
is.pop();
}
res[j] = '\0';//从不忘记为字符数组的最后以为加上结束符 方便进行下面的strcpy
strcpy(res_str, res); return res_str;
} void main()
{
int n, m;
char data[];
char res_str[];
cout << "请输入M、N的值(N进制转换为M进制): " << endl;
cin >> n >> m;
cout << "请输入转换的数值: " << endl;
cin >> data;
cout << "把数值" << data << "由" << n << "进制" << "转换为" << m << "进制的结果为:";
cout << ntom(n, m, data, res_str) << endl; system("pause");
} // run out:
/*
请输入M、N的值(N进制转换为M进制):
10 16
请输入转换的数值:
100
把数值100由10进制转换为16进制的结果为:64
请按任意键继续. . .
*/

(22)写一个函数求整型数组中的次大数。

程序代码如下:

 #include<iostream>
using namespace std; // 写一个函数找出一个整数数组中第二大的数(次大数)
int Max2(int ar[], int n)
{
int Max1 = ar[] > ar[] ? ar[] : ar[];
int Max2 = ar[] > ar[] ? ar[] : ar[];
for (int i = ; i < n; i++)
{
if (ar[i] > Max2)
{
Max2 = ar[i];
}
if (ar[i] > Max1)
{
Max2 = Max1;
Max1 = ar[i];
}
} return Max2;
} void main()
{
int ar[] = {, , , , , , , };
cout << Max2(ar, ) << endl; //
system("pause");
}

(23)写程序实现由键盘输入内容,并将内容保存到一个文本文件中。

程序代码如下:

 #include<iostream>
#include<fstream>
using namespace std; void main()
{
ofstream fout("test.txt");// 定义输出文件流并打开文件得2分
if (!fout)
{
cerr << "文件没有打开!" << endl;
exit();
}
int x;
cin >> x;
while (x != -)
{
fout << x << ' ';
cin >> x;
} // 能够从键盘向文件正确输出数据得6分 fout.close();// 关闭输出文件流得1分
}

(24)写一个函数从字符串N中查找子串字符串M第一次出现的位置。

程序代码如下:

 #include <iostream>
using namespace std; // 在字符串n中查找第一次出现子串m的索引值
int StrStr(const char *src, const char *sub)
{
const char *bp;
const char *sp;
int nIndex = -;
if ((NULL == src)||(NULL == sub))
{
return nIndex;
} while (*src)
{
bp = src;
sp = sub;
do
{
if (!*sp)
{
return nIndex;
}
} while (*bp++ == *sp++); ++src;
++nIndex;
} return -;
} void main()
{
char *pStr = "abcdefghijklmn";
char *pDes = "ghi";
char *pSec = "sec";
cout << StrStr(pStr, pDes) << endl; //
cout << StrStr(pStr, pSec) << endl; // -1
cout << StrStr(pStr, NULL) << endl; // -1
cout << StrStr(NULL, pSec) << endl; // -1
system("pause");
}
// run out:
/*
5
-1
-1
-1
请按任意键继续. . .
*/

(25)有N个大小不等的自然数(1--N),请将它们由小到大排序。

要求程序算法:时间复杂度为O(n),空间复杂度为O(1)。

算法:N个不等的自然数1~N,排序完成后必然为1~N。

所以可以一次遍历,遇到a[i] != i的就把a[i] 和 a[a[i]]交换。

函数实现以及测试代码如下:

 #include <iostream>
using namespace std; void sort(int a[], int n)
{
int i;
int t; /*临时变量:空间复杂度O(1)*/ for (i = ; i < n + ; ++i) /*时间复杂度O(n)*/
{
while (a[i] != i)
{
t = a[a[i]];
a[a[i]] = a[i]; // 排好一个元素
a[i] = t;
}
}
} void print(int a[], int n)
{
for (int i = ; i < n; ++i)
{
cout << a[i] << " ";
}
} void main()
{
int nArray[] = {, , , , , , , , , };
sort(nArray, );
print(nArray, );
system("pause");
} // run out:
// 0 1 2 3 4 5 6 7 8 9 请按任意键继续. . .

(26)建立单链表,把'a'--'z'26个字母插入到单链表中,并且倒叙,再打印数据。

程序实现以及测试程序如下:

 #include <stdio.h>
#include <stdlib.h> // 单连表的建立,把'a'--'z'26个字母插入到连表中,并且倒叙,还要打印!
typedef struct link_node
{
char data;
struct link_node *next;
}node, *pNode; void print(pNode head)
{
if (NULL == head || (head->next == NULL))
{
return;
}
pNode p = head->next;
while (p != NULL)
{
printf(" %c ", p->data);
p = p->next;
}
printf("\n");
} void main(void)
{
pNode p = NULL;
pNode q = NULL; pNode head = (pNode)malloc(sizeof(node));
head->data = ' ';
head->next = NULL; pNode firstNode = (pNode)malloc(sizeof(node));
firstNode->data = 'a';
firstNode->next = NULL;
head->next = firstNode;
p = firstNode; int longth = 'z' - 'b';
int i = ;
while (i <= longth )
{
pNode tempNode = (pNode)malloc(sizeof(node));
tempNode->data = 'b' + i;
tempNode->next = NULL;
q = tempNode; head->next = tempNode;
tempNode->next = p;
p = q;
i++;
} print(head); system("pause");
}
// run out:
/*
z y x w v u t s r q p o n m l k j i h g f e d c b a
请按任意键继续. . .
*/

(27)用指针的方法,将字符串“ABCD1234efgh”前后对调显示。

程序实现以及测试程序如下:

 #include <stdio.h>
#include <string.h>
#include <stdlib.h> void main()
{
char str[] = "ABCD1234efgh";
int length = strlen(str);
char * p1 = str;
char * p2 = str + length - ;
while (p1 < p2)
{
char c = *p1;
*p1 = *p2;
*p2 = c;
++p1;
--p2;
}
printf("str now is %s\n", str);
system("pause");
}
// run out:
/*
str now is hgfe4321DCBA
请按任意键继续. . .
*/

(28)《 字符串匹配KMP算法

(29)编写一个不定形参的函数(计算不计数的实参的平均数)

程序示例代码如下:

 #include <stdio.h>
#include <stdlib.h> #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
// 4 + 4 - 1 = 7 // 4-1 = 3
// 0111 // ~0011 = 1100
// 0111 & 1100 = 0100 = 4
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
// 指针 = (char*)&V(数值个数) + 4
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
// (*(int *)((指针ap += INTSIZEOF(int)) - INTSIZEOF(int)))
// *(int *) ((ap = ap + INTSIZEOF(int)) - INTSIZEOF(int))
// *(int *)(本段代码执行结果ap向前走4个字节,但是地址不变)
#define va_end(ap) ( ap = (va_list)0 )
// ap = (char *)0 int average(int n_values, ...)
{
int sum = ; va_list var_arg; // char * va_start(var_arg, n_values); for (int i = ; i < n_values; ++i)
{
sum += va_arg(var_arg, int);
} va_end(var_arg);
return sum / n_values;
} void main()
{
printf("%d \n", average(, , , )); //
system("pause");
}

(30)计算无符号长整型的二进制每四位的和。

程序代码如下:

 #include <iostream>
using namespace std; int Count(unsigned long value)
{
int sum = ;
while (value)
{
sum += value & 0x0f;
value >>= ;
} return sum;
} void main()
{
cout << Count() << endl; // 0000 1010 1101 0101 // 0 + 10 + 13 + 5 = 28
system("pause");
}

(31)字符串类String的实现。请参见随笔《 字符串String

(32)

(33)

(34)

(35)

Good Good  Study, Day Day Up.

顺序  选择  循环  总结