- 编码完成下面的处理函数,函数将字符串中星字符星到字符串的前部分,
前面的非星字符后移,但是不能改变非字符的先后顺序,函数返回字符串中非星字符的数量。
例如:原始串为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;
}
- 判短一个数字是否是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;
}
- 将字符串数组从第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;
}
- 查找一个数组中,数字个数超过数组长度一半的数字
解题思路
将数字按顺序排列,这样相同的数字就会被排列到一起,出现次数超过一半,则说明若该数字下标为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;
}