题目一
问题:
编码完成下面的处理函数。 函数将字符串中的字符*
到串的前部分,前面的非*
字符后移,但不能改变非*
字符的先后顺序,函数返回串中字符*
的数量。 如原始串为:ab**cd**e*12
, 处理后为*****abcde12
,函数并返回值为5
。
(要求使用尽量少的时间和辅助空间)
思路讲解:
- 第一步,要构造一个交换函数,可以交换两个指针指向的内容;
- 构造函数主体,首先创建两个指针指向字符串末尾,控制两个指针向前遍历,其中一个指针始终指向最后一个
*
,另一个指针始终指向最后一个*
前面的第一个非*
字符,调用第一步的交换函数,交换两个指针指向的内容,就可以把*
前移。
C语言代码
#include "stdio.h"
#include "string.h"
//指针内容交换函数
void exchange_str(char* p, char* q){
char temp = *p;
*p = *q;
*q = temp;
}
//功能函数主体
int sort(char* str ){
int length = strlen(str);
char* s1 = str+length-1;
char* s2 = str+length-1;
//在最后一次交换函数执行后,整个字符串已经完成,此时s2指向最后一个*,
//由于s2前面没有非*字符,所以s1会自己自减到字符串首地址的前一个地址,
//所以以此来判断任务完成
while (s1 > str){
//s2始终指向最后一个'*'
while(*s2 != '*')
s2--;
s1 = s2-1;
//s1始终指向s2前面的第一个非'*'字符
while(*s1 == '*')
s1--;
exchange_str(s1,s2);
}
return s2-s1;
}
int main(void)
{
char str[] = "ab**cd**e*12";
int num = sort(str);
printf("%d\n",num);
printf("%s\n",str);
while(1);
return 0;
}
运行结果
题目二
问题:
两个按从小到大排好序的数组,构造一个函数高效得判断这两个数组中是否存在相同的数字。
思路讲解:
题目已经提供了两个排好序的数组,不需要遍历整个数组,只需要取两个数组的首地址
,让指向内容小的指针自增,去追赶指向内容大的指针,在这个过程中如果两个指针指向内容相等,则有相同的值,整个过程结束还没有说明没有相同的值。
假如一个数组长度为5,另一个为10,传统遍历要执行5*10=50次,这个方法最多遍历10+5=15次.
C语言代码
#include "stdio.h"
#include "stdbool.h"
bool have_same(int* a, int* b, int a_len, int b_len){
int* p ,* q; //定义两个指针变量,作为监视哨
p = a;
q = b;
int* b_end = b + b_len;
int* a_end = a + a_len;
while(p < a_end && q < b_end){ //防溢出
if(*p < *q){
p++;
}
else if(*p > *q){
q++;
}
else {
return true;
}
}
return false;
}
int main(void)
{
int a[10] = {5,6,7,8,9,10,77,88,99,109};
int b[5] = {0,1,2,3,11};
int a_len = sizeof(a)/sizeof(int);
int b_len = sizeof(b)/sizeof(int);
if(have_same(a,b,10,5))
printf("have same");
else
printf("no same");
while(1);
}
运行结果
题目三
问题:
对一已经从小到大排序好的数组使用二分法查找某一数字,找到并输出其下标,若找不到返回-1。
思路讲解:
二分法查找数字是很基本的算法,整个过程中需要三个量,首值、中值、末值的索引;通过循环不断判断目标值与中值的大小关系,改变首、中、末索引,直到找到或结束循环输出-1。
C语言代码
#include "stdio.h"
int dichotomy(int find_num, int* array, int len){
int star,mid,end;
star = 0;
end = len-1;
while(star <=end){
mid = (end+star)/2;
if(array[mid] > find_num){
star = star;
end = mid-1;
}
else if (array[mid] < find_num){
end = end;
star = mid+1;
}
else
return mid;
}
return -1;
}
int main(void)
{
int a[9] = {5,6,7,8,9,11,77,88,99};
while(1){
int find_num ;
scanf("%d",&find_num);
int b =dichotomy(find_num,a,9);
printf("%d\n\n",b);
}
运行结果