目录
25、实现字符串的排序。(输入hello world good,输出good hello world,其中字符串个数任意)
26、输入两个有序的字符串(从小到大),合并成一个有序的字符串。(输入cdhxyz fjln 输出cdfhjlnxyz)
27、命令行参数实现字符串排序。
28、一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序(异或)找出这两个只出现一次的数字。
29、编写一个函数来查找字符串数组中的最长公共前缀。(输入abca abc abca abc abcc 输出 abc)
30、给定一个字符串,字符串是有序的整数(位数不限)集合,逗号相连,移除相同的数字,使每个数字只出现一次,输出最终的数字个数。例如输入:0,0,1,1,1,2,2,31,31,444 输出 5
上一篇复习了数组指针和指针数组、指针的指针和命令行参数,这一节完成最后6道编程题。
说明:我们学过单片机的一般都是有C语言基础的了,网上关于C语言的资料有很多,大家如果对C语言不熟悉的话可以先去详细学一下,再以这篇博文作为复习资料学习。
这篇博文的目的是复习C语言,我们会陆续以30多个编程题作为复习要点,这30多个编程题基本涵盖了C语言所有的内容了,只要你掌握了这30多个编程题,那么你的C语言基本就没什么问题了。
注意:由于本专栏是嵌入式全栈开发专栏,为了我们能熟悉以后实际工作中的开发环境,我们写C语言全部在Linux中的vim编辑器中写,这么做事为了我们能够熟练掌握Linux系统的常用命令以及Linux上的vim编辑器的常用工作命令,以达到对口训练的目的!
vim编辑器的一些工作命令在上一篇博文中已经详细介绍过了,如果不了解可以先去看看。
我们正式开始:
25、实现字符串的排序。(输入hello world good,输出good hello world,其中字符串个数任意)
提示:先申请一个空间获取输入的字符串,每一个空格为一个字符串,然后再申请一个空间存放每一个字符串的地址,再通过指针数组中的每一个指针对每一个字符串进行排序。
参考代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void sort(char**s, int count)
{
int i,j;
for(i=0;i<count-1;i++)//s中的元素
{
for(j=0;j<count-1-i;j++)//元素中的每一个字符
{
if(strcmp(s[j],s[j+1])>0)
{
//交换地址
char *t=s[j];
s[j]=s[j+1];
s[j+1]=t;
}
}
}
}
void save_each_str_add(char*str, char**s)
{
int i=0;
char*begin=str;//将字符串的地址记住
//当没有遇到字符串结束标志时就继续
while(*str!='\0')
{
if(*str==' ')//当遇到空格时就说明是一个字符串了,就给该字符串申请空间
{
s[i]=(char*)malloc(sizeof(char)*(str-begin));
//将该字符串拷贝进刚刚申请的空间
strncpy(s[i++],begin,str-begin);
begin=str+1;//str指向空格后一个字符作为下一个起始位置
}
str++;
}
//当*str等于结束标志标志退出循环时,记得将最后一个字符串的地址存进去
s[i]=(char*)malloc(sizeof(char)*(str-begin));
strncpy(s[i++],begin,str-begin);
}
int main()
{
//获取输入
char str[1028]={0};//数组的大小一定要写,够用就行
char ch;
int i=0;
int count=0;//获取字符串的同时,计算单词的个数
while((ch=getchar())!='\n')//只要不换行就继续获取
{
if(ch==' ')
{
count++;//如果是空格就++
}
str[i++]=ch;//将获取到的字符依次存放到str数组中
}
count++;
//申请一个指针数组空间
char **s=(char**)malloc(sizeof(char*)*count);//有多少个字符串count就申请多大空间,申请的空间类型是char*型的地址则是char**,而存放的类型是char*
//将每一个字符串的地址存放在指针数组中
save_each_str_add(str,s);//将总的输入和指针数组空间的地址传过去
//对s数组中的指针对字符串进行排序
sort(s,count);
//打印s
for(i=0;i<count;i++)
{
printf("%s ",s[i]);
}
printf("\n");
//释放空间
for(i=0;i<count;i++)
{
free(s[i]);
}
free(s);
return 0;
}
运行结果:
26、输入两个有序的字符串(从小到大),合并成一个有序的字符串。(输入cdhxyz fjln 输出cdfhjlnxyz)
提示:获取两个字符串数组和一个空数组,依次比较数组1和数组2对应位置的字符大小,把小的放到数组3中,当比到其中一个数组的’\0’时,就停止比较,将另一个数组中剩下没有比较的字符直接接到数组3的字符串后面即可。
参考代码:
#include <stdio.h>
#include <string.h>
void merge(char*s1, char*s2, char*s3)
{
while(*s1!='\0' && *s2!='\0')
{
if(*s1<*s2)
{
*s3++=*s1++;
}
else
{
*s3++=*s2++;
}
}
if(*s1=='\0')
{
strcat(s3,s2);
}
if(*s2=='\0')
{
strcat(s3,s1);
}
}
int main()
{
char s1[128]={0};
char s2[128]={0};
char s3[128]={0};
scanf("%s %s",s1,s2);
merge(s1,s2,s3);
printf("%s\n",s3);
return 0;
}
运行结果:
27、命令行参数实现字符串排序。
参考代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void sort(int size, char*str[])
{
int i,j;
for(i=0;i<size-1;i++)
{
for(j=0;j<size-1-i;j++)
{
if(strcmp(str[j],str[j+1])>0)
{
char*t=str[j];
str[j]=str[j+1];
str[j+1]=t;
}
}
}
}
int main(int argc, char*argv[])
{
sort(argc-1, argv+1);
int i,j;
for(i=1;i<argc;i++)
{
printf("%s ",argv[i]);
}
printf("\n");
return 0;
}
运行结果:
27、命令行参数实现字符串排序。
参考代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void sort(int size, char*str[])
{
int i,j;
for(i=0;i<size-1;i++)
{
for(j=0;j<size-1-i;j++)
{
if(strcmp(str[j],str[j+1])>0)
{
char*t=str[j];
str[j]=str[j+1];
str[j+1]=t;
}
}
}
}
int main(int argc, char*argv[])
{
sort(argc-1, argv+1);
int i,j;
for(i=1;i<argc;i++)
{
printf("%s ",argv[i]);
}
printf("\n");
return 0;
}
运行结果:
28、一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序(异或)找出这两个只出现一次的数字。
提示:假设一个整型数组是:1 1 2 2 3 4
0001
0001
0010
0010
0011
0100
他们放在一起异或结果就是3^4
结果 0011 ^ 0100
0111
0111就说明了3和4的最后三位不同
取这三位中的任何一位都能计算
假设取左边开始下标为2的
所有数字中,凡是左边开始下标为二是1的放在一组
0100
凡是左边开始下标为二不是1的放在一组
0001
0001
0010
0010
0011
这两组数字,第一组全部异或 结果0100 即4
第二组全部异或 0011 即3
参考代码:
#include <stdio.h>
int find_one(int r)
{
int i;
for(i=0;i<32;i++)
{
if(r&1==1)
{
return i+1;//第i+1位是1
}
r>>=1;//右移位继续找
}
return -1;
}
int main()
{
int i, result=0;
int num1=0,num2=0;
int array[10]={1,1,2,2,3,3,4,5,6,6};
for(i=0;i<10;i++)
{
result^=array[i];
}
//找出异或的结果为1的二进制位,然后以此为标准来分组
int index=find_one(result);
//从右往左开始找,如果第i+1(index)位是1则分为一组,如果是0就分为一组
for(i=0;i<10;i++)
{
//判断第index位是不是1
//将每个元素的二进制位下标为index-1的位跟1相与
if((array[i]>>(index-1))&1==1)
{
//组内异或得出结果
num1^=array[i];
}
else
{
num2^=array[i];
}
}
printf("%d %d \n",num1, num2);
return 0;
}
运行结果:
29、编写一个函数来查找字符串数组中的最长公共前缀。(输入abca abc abca abc abcc 输出 abc)
提示:
第一步:获取字符串:定义一个指针数组,申请一块内存,指针数组中每一个指针指向该内存,将获取到的几个字符串对应放到每一个指针所指针的内存中。
第二步:找出最短字符串:如果字符串下标为0,就计算该字符串的长度存在short_len中。如果字符串的下标不为0且如果该字符串的长度小于最小长度,就将该下标记录在min中,然后将该字符串的长度更新到short_len中。
第三步:将最短字符串和其他字符串比较,看看是否是它的最长前缀。
参考代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
//获取字符串
char*str[5]={0};//存放5个字符串的地址
//找出最短字符串
int i,j;
int min;//记录最短字符串的编号
int short_len;//记录最短字符串的长度
char sub[32]={0};//将最短字符串拷贝进去
for(i=0;i<5;i++)
{
str[i]=(char*)malloc(sizeof(char)*32);
scanf("%s",str[i]);
if(0==i)
{
min=i;
short_len=strlen(str[i]);
}
else
{
if(strlen(str[i])<short_len)
{
min=i;
short_len=strlen(str[i]);
}
}
}
//找出最长公共前缀
//把最短字符串依次和每一个字符串比较,如果都相等,说明是公共子串,如果有一个不相等,就将最短字符串缩短一个字符,再进行对比,如此反复循环,次数等于最短字符串的长度
for(i=short_len;i>=1;i--)
{
//拷贝之前先清空掉sub
memset(sub,0,32);
//将最短字符串拷贝到一个sub中
strncpy(sub,str[min],i);
//判断是不是公共子串
for(j=0;j<5;j++)
{
if(strncmp(sub, str[j],i)!=0)//i为子串的长度
{
break;//说明不是子串,直接跳出j这层循环,i--缩短子串的长度
}
}
if(j==5)
{
printf("最长公共子串是%s\n", sub);
return 0;
}
}
printf("公共子串不存在\n");
return 0;
}
运行结果:
30、给定一个字符串,字符串是有序的整数(位数不限)集合,逗号相连,移除相同的数字,使每个数字只出现一次,输出最终的数字个数。例如输入:0,0,1,1,1,2,2,31,31,444 输出 5
提示:
第一步:定义两个数组,一个数组用来获取字符串,然后先将这个字符串转换成数字放在一个数组里面。atoi()函数:将字符串(以’\0’位分界面)转换成int型的数字,参数只要提供字符串的地址。
第二步:将重复的数字给去除掉,再统计个数
参考代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int str_to_int(char*str, int*array)
{
char*begin=str;//记录下开始位置
int i=0;//数组的下标
//如果没有到'\0'就继续循环
while(*str!='\0')
{
//如果遇到逗号就将逗号转换成'\0',分割成一个子串,然后将子串转换成int型
if(*str==',')
{
*str='\0';
//转换
array[i++]=atoi(begin);
//更新起始位置
begin=str+1;
}
str++;
}
//退出循环后不要忘记转换最后一个数字
array[i]=atoi(begin);
return i+1;//返转换成数字的个数
}
int count_dif(int*array, int size)
{
int i;
int count_dif=0;
for(i=0;i<size;i++)
{
if(0==i)
{
//数组第一个元素直接计算一次
count_dif++;
continue;//跳到i++
}
//之后只有当后一个数与前一个数不相等时才计算一次
if(array[i]!=array[i-1])
{
count_dif++;
}
//如果相等就直接不计算了,继续i++
}
return count_dif;
}
int main()
{
//定义两个数组
char str[128]={0};
int array[128]={0};
//获取一个字符串
scanf("%s", str);
//将字符串转换成int数字
int count=str_to_int(str, array);
//计算不重复的个数
printf("%d\n", count_dif(array, count));
return 0;
}
运行结果:
以上就是这篇内容,如想了解更多,欢迎订阅本专栏!
如有问题可评论区或者私信留言,如果想要进交流群请私信!