由于题目所给出的限制,无法用循环嵌套。
#include <stdio.h>
int main()
{
char arr[] = "abaccdef";
int arr1[200] = { 0 };//创建一个数组,用于计算每个元素出现的个数
char* p = arr;
while (*p)//这层循环用于计算每个元素出现的个数
{
arr1[*p]++;/*注意:这里直接用arr内的字符对应的ASCLL码值作为
存储于arr1内的元素下标。当数组中出现重复字符时,直接就可以找
到对应的下标进行++。*/
p++;
}
p = arr;//p重新赋值为首元素地址,方便查找
while (*p)//这层循环的目的是找到第一个出现一次的字符元素。
{
if (arr1[*p] == 1)//如果找到的元素出现个数为1,那么打印他!
{
printf("%c", *p);/*此时*p所指向的是出现次数为1的元素,
且由于是从首元素开始向后查找,也能保证他是第一个出现的*/
return 0;
}
p++;
}
}
这个做法的巧妙之处就在于,直接用字符所代表的的ASCLL码值来作为用于计算字符出现个数的数组的下标,下次出现时,无需找其他的元素,只需要++自己就可以了。
而且,在查看arr1内的出现次数时,也根本无需遍历查找,只需要依次查找坐标为*p的元素,大大提高了效率。
需要注意的一点是,arr1的大小应该包含ASCLL码值所能表示字符的最大范围,否则可能包含不到ASCLL码值过大的字符。
下面这道题目也是同理。
输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入 ”They are students.” 和 ”aeiou” ,则删除之后的第一个字符串变成 ”Thy r stdnts.”
#include <stdio.h>
int main()
{
char arr1[] = "They are students.";
char arr2[] = "aeiou";
int arr3[130] = { 0 };
char* p = arr2;
while (*p)
{
arr3[*p++]++;
}
//以arr2中的字符所代表的ASCLL码值为下标,在arr3中记录他们是否出现
p = arr1;
while (*p)
{
if (arr3[*p] > 0)/*如果arr1的元素在arr2中出现,那么arr3中以这
这个元素的ASCLL码值为下标的元素肯定比0大*/
{
char* m = p;
for (; *m != '\0'; m++)
{
*m = *(m + 1);
}
}
else
p++;
}
//这层循环目的是在arr3中依次判断arr1中的元素是否在arr2中出现过
printf("%s", arr1);
return 0;
}
相当巧妙。