1. 不用循环和递归,实现打印数字0到15。
利用宏定义的原地替换
#define FourPrintf(A) A;A;A;A;
FourPrintf(FourPrintf(printf("%d\n", a++)));
2. 写一个函数找出一个整数数组中第二大的数。
首先找到最大的数,放在第0位,然后在剩下的数组中找最大的数,放在第1位,如果跟第一次一样大,继续往后找。
int FindMax(int arr[], int size)
{
int index = 0;
int max = arr[0];
int i;
for (i = 1; i < size; i++) {
if (max < arr[i]) {
max = arr[i];
index = i;
}
}
return index;
}
void swap(int *a1, int *a2)
{
if (a1 != a2)
{
int tmp = *a1;
*a1 = *a2;
*a2 = tmp;
}
return;
}
void Find2ndMax()
{
int a[6] = {1, 3, 7, 4, 5, 9};
int size = sizeof(a) / sizeof(int);
int maxindex = FindMax(a, 6);
int max = a[maxindex];
swap(&a[0], &a[maxindex]);
int nextindext;
int nextmax;
int i = 0;
while (1)
{
i++;
size--;
if (size == 0)
break;
nextindext= FindMax(a+i, size);
if (a[i+nextindex] != max)
return a[i+nextindex];
else
swap(&a[i], &a[i+nextindext]);
}
return -1;
}
3. strcmp函数
int mystrcmp(const char *str1, const char*str2)
{
int ret = 0;
while (!(ret = *str1 - *str2) && *str2)
{
str1++;
str2++;
}
if (ret > 0)
return 1;
else if (ret < 0)
return -1;
else
return 0;
}
4. 字符串逆序
要注意字符串的长度,如果等于sizeof(buf)/sizeof(char),要减1
char a[] = "abcdefg1234";
int size = sizeof(a) / sizeof(char) - 1;
或者 int size = strlen(a);
5. 请编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,该字符串是由同一字符组成的
/*
参数str 被查找的字符串 target 要查找的子串字符 pindex 输出参数,用户返回子串下标
返回值 最长子串长度
*/
int getLongestSubstr(char *str, const char target, int *pindex)
{
char *pos1 = NULL, *pos2 = NULL;
int maxlen = 0;
char *begin = str;
*pindex = -1;
while (*str)
{
if (*str == target)
{
pos1 = str;
pos2 = pos1 + 1; //注意这里不能用pos1++,pos1不能改变
while (*pos2 == target) {
++pos2;
}
if (pos2 - pos1 > maxlen) {
maxlen = pos2 - pos1;
*pindex = pos1 - begin;
}
}
str++;
}
return maxlen;
}
6. 读文件 file1.txt 的内容(例如):
12
34
56
输出到 file2.txt :
56
34
12
先整个字符串逆序,再各个部分逆序。
void swap(char *begin, char *end)
{
char tmp;
while (begin < end)
{
tmp = *begin;
*begin = *end;
*end = tmp;
begin++;
end--;
}
return;
}
void transferStr(char *str)
{
swap(str, str + strlen(str) - 1);
char *pos = str;
char *begin = NULL, *end = NULL;
while (*pos)
{
begin = pos;
while (*begin && (*begin == '\n'))
begin++;
end = begin;
while (*end && (*end != '\n'))
end++;
pos = end;
end--;
swap(begin, end);
}
cout << str << endl;
}
7. 有两个双向循环链表 A,B,知道其头指针为:pHeadA,pHeadB,请写一函数将两链表中 data 值相同的结点删除。
遍历其中一条链表,然后删除另一条链表这个节点的数据,如果删除成功,再删除这个链表。注意要找到这个链表的下一个节点。
int delete_node(Node *phead, int data)
{
Node *pnode = phead->pnext;
Node *psave;
int ret = -1;
while (pnode != phead)
{
psave = pnode->pnext;
if (pnode->data == data) {
pnode->pnext->pprev = pnode->pprev;
pnode->pprev->pnext = pnode->pnext;
free(pnode);
ret = 0;
}
pnode = psave;
}
return ret;
}
void deleteSameData(Node *p1, Node *p2)
{
int size1 = get_size(p1);
int size2 = get_size(p2);
Node *phead1, *phead2;
phead1 = size1 < size2 ? p1 : p2;
phead2 = size1 < size2 ? p2 : p1;
Node *pnode = phead1->pnext;
Node *psave;
while (pnode != phead1)
{
psave = pnode->pnext;
if (delete_node(phead2, pnode->data) == 0)
{
while ((psave != phead1) && (psave->data == pnode->data))
psave = psave->pnext;
delete_node(phead1, pnode->data);
}
pnode = psave;
}
return;
}
8. 给定字符串 A 和 B,输出 A 和 B 中的最大公共子串。
方法1:利用strstr
先确定哪个是较短的字符串,然后使用短字符串的子串,从长到短,与长字符串比较。
int getLongestCommonStr(const char *str1, const char *str2, char *common)
{
int size1 = strlen(str1);
int size2 = strlen(str2);
int size = size1 < size2 ? size1 : size2;
const char *pshort = size1 < size2 ? str1 : str2;
const char *plong = size1 < size2 ? str2 : str1;
int i, j;
char buf[128] = {0};
for (i = size; i >= 1; i--)
{
for (j = 0; j + i <= size; j++)
{
bzero(buf, sizeof(buf));
memcpy(buf, &pshort[j], i);
if (strstr(plong, buf)) {
strcpy(common, buf);
return 0;
}
}
}
return -1;
}
方法2:
void getLongestCommonStr(const char *p1, const char *p2, char *common)
{
int size1 = strlen(p1);
int size2 = strlen(p2);
const char *pshort = size1 < size2 ? p1 : p2;
const char *plong = size1 < size2 ? p2 : p1;
const char *pshort1, *plong1;
int len, maxlen = 0;
while (*pshort)
{
pshort1 = pshort;
plong1 = plong;
while (*plong1 && (*plong1 != *pshort1))
plong1++;
if (*plong1 != '\0')
{
len = 0;
while (!(*plong1 - *pshort1) && *pshort1) {
plong1++; pshort1++;
len++;
}
if (len > maxlen) {
maxlen = len;
memcpy(common, pshort, len);
}
}
pshort++;
}
return;
}
9. n*n矩阵,矩阵沿45度递增
0 1 5
2 4
3
void juzhen(int n)
{
int x, y;
int lie, begin;
int val;
int arr[20][20] = {0};
for (x = 0; x < n; x++)
{
for (y = 0; y < n; y++)
{
if (x + y < n) { //左侧
lie = x + y;
begin = lie * (lie+1)/2;
val = begin + (lie % 2 == 1 ? y : x);
}
else { //右侧
lie = 2*(n-1) - x - y;
begin = n * n - (lie+1)*(lie+2)/2;
val = begin + (lie % 2 == 0 ? (n - 1 - y) : (n - 1 -x));
}
arr[x][y] = val;
}
}
for (y = 0; y < n; y++)
{
for (x = 0; x < n; x++)
printf("%5d",arr[y][x]);
printf("\n");
}
return;
}
10.移位
char short类型在进行运算时,都会先转为类型。
int main()
{
unsigned char a = 0xa5;
unsigned char b = ~a>>4+1; //优先级 ~ 大于+ 大于>>
printf("%d\n", b); //250
return 0;
}
11. 分解质因数
8 = 2 * 2 * 2
6 = 2 * 3
void fenJieZhiYinShu(int a)
{
int i;
int tmp = a;
int flag = 0;
for (i = 2; i < a; i++)
{
while (tmp % i == 0)
{
printf("%d\n", i);
tmp /= i;
flag = 1;
}
if (tmp == 1)
break;
}
if (flag == 0)
printf("i cannot\n");
return;
}
程序员面试宝典上题目
1. zigzag数组:输入n,求一个nXn矩阵,规定矩阵沿45度递增,形成一个zigzag数组
http://www.cnblogs.com/Dzhouqi/p/3628129.html
https://blog.csdn.net/u013074465/article/details/43062985
2. 螺旋数列
https://blog.csdn.net/gebushuaidanhenhuai/article/details/74858187
3. 矩阵
https://blog.csdn.net/willmu/article/details/7179650
4. i++
*(p++)+=123;
无论有没有括号,p++都是先使用p,再++
int main()
{
int arr[] = {6, 7, 8, 9, 10};
int *ptr = arr;
*(ptr++)+=123; //arr[0] 加123, 这一步之后ptr指向第二个元素
printf("%d\n", arr[0]);
printf("%d\n", arr[1]);
printf("%d,%d\n", *ptr, *(++ptr));
return 0;
}
129
7
7,8
也有的答案说是打印8,8,解释是这样的:
printf计算参数时是从右到左压栈的,先计算*(++ptr),然后再计算*ptr,所以是8,8