面试题练习

  1. 编码完成下面的处理函数,函数将字符串中星字符星到字符串的前部分,
    前面的非星字符后移,但是不能改变非字符的先后顺序,函数返回字符串中非星字符的数量。
    例如:原始串为ABC**D**E**FG*HIJ,处理后为*******ABCDEFGHIJ函数返回10.
    函数原型:void MoveStr(char *str);
    要求:不得创建新的数组
    解题思路
    通过观察发现,需要实现将字符串中的星号移动到字符串的最前面,因此我可以将这个问题看待成,将字符串以星号为分割点依次分割。
    因此上述字符可分割为:(ABC星)星)D星)星)E星)星)FG星)HIJ)
    因此设定2个指针变量,一个指向字符串的起点,一个指向每次遇见星号的节点,在小范围内进行交换,将星号移动到最前段。
    第一次头指针指向A,位指针应该指向第一个星号,在此区间内进行字符串交换,将星号移动到最前端,之后头指针++,因为若不移动,则头指针指向为星号,那下次移动次数将增加,未指针也因为指向的为C因此,为指针++。
    依次类推,依次进行检索,判断,直到为指针判断到字符串结束符“\0”停止
    程序实现
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void MoveStr(char *str)
{
	char *p1 = str;
	char *p2 = str;
	int a = 0;
	char tmp = 0;
	int i;
	while (*p2!=0)
	{
		while (*p1 == '*')   //若开始为*则不需要移动,指针后移
		{
			p1++;
			p2++;
		}
		while (*p2 != '*'&&*p2 != 0)
		{
			p2++;
		}
		if (*p2 != 0)
		{
			a = p2 - p1;
			for (i = 0; i < a; i++)
			{
				tmp = *(p2 - i);
				*(p2 - i) = *(p2 - i - 1);
				*(p2 - i - 1) = tmp;
			}
			p1++;
		}
	}
}

int main()
{
	char arr[20] = {"****"};
	MoveStr(arr);
	printf("%s", arr);
	system("pause");
	return 0;
}
  1. 判短一个数字是否是2的K次方
    解题思路
    2的K次方的数字都有同一个共同特征,在2进制比特位中只有一位数字是1,其余全部为0,因此我只需要判断一个数字的比特未上有多少个1。
    若一个数字只有一个比特位是1,那么n&(n-1)==0
    程序实现
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

void is_tow(int n)
{
	if (n < 1)
	{
		printf("不是该类型数字\n");
	}
	int m = n & (n - 1);
	if (m == 0)
	{
		printf("是该类型数字\n");
	}
	printf("不是该类型数字\n");
}

int main()
{
	int num = 0;
	printf("请输入一个整数:");
	scanf("%d", &num);
	is_tow(num);
	system("pause");
	return 0;
}
  1. 将字符串数组从第n位开始翻转
    解题思路
    统计字符长度,从第n位开始逆序
    程序实现
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>

void revovle(char *str, int n)
{
	int len = 0;
	int r = 0;
	int l = 0;
	char tmp = 0;
	len = strlen(str) - 1;
	l = len;
	r = n - 1;
	while(r <= l)
	{
		tmp = *(str + r);
		*(str + r) = *(str + l);
		*(str + l) = tmp;
		r++;
		l--;
	}
	assert(str != NULL);
	if (str == NULL)
		printf("指针为空\n");

}
int main()
{
	int n = 0;
	char arr[] = { "abcdefg" };
	printf("从第几个字符开始反转\n");
	do
	{
		scanf("%d", &n);
		if (n < 0)
			printf("n不能为负数,重新输入:");
		else if (n>sizeof(arr))
			printf("n值超过字符串长度,重新输入:");
		else break;
	} while (1);
	revovle(arr, n);
	printf("%s", arr);
	system("pause");
	return 0;
}
  1. 查找一个数组中,数字个数超过数组长度一半的数字
    解题思路
    将数字按顺序排列,这样相同的数字就会被排列到一起,出现次数超过一半,则说明若该数字下标为i,则在i+strlen/2时2个所对应的数字相同。因此排好顺序之后,只需要将数组按照这种规律检索一半,成立则找出该数字,不成立,则无次数字。
    程序实现
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

int main()
{
	int i = 0;
	int j = 0;
	int tmp = 0;
	int size = 0;
	int arr[] = { 2, 3, 2, 4, 2, 2, 8, 2, 1, 2 };
	size = sizeof(arr) / sizeof(arr[0]);
	int mid = size / 2;
	for (i = 0; i < size - 1; i++)
	{
		for (j = 0; j < size - 1 - i;j++)
		if (arr[j]>arr[j + 1])
		{
			tmp = arr[j];
			arr[j] = arr[j + 1];
			arr[j + 1] = tmp;
		}
	}
	for (i = 0; i < mid; i++)
	{
		if (arr[i] == arr[i + mid])
		{
			break;
		}
	}
	if (i==mid)
	    printf("没有出现次数超过该数组长度一半的数字\n");
	else
		printf("%d为次数超过该数组长度一半的数字\n",arr[i]);
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值