算法思路:
第一种方法:“蛮力法”
最简单的方法就是把这个字符串看作是一个字符数组,对该数组使用双重循环进行遍历,如果发现有重复的字符,就把该字符置为’\0’,最后再把这个字符数组中所有的’\0’去掉,此时得到的字符串就是删除重复字符后的目标字符串。
//代码展示助于理解
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[10];
gets(str);
int len = strlen(str);
for (int i = 0; i < len; i++)
{
for (int k = i + 1; k < len; k++)
{
if (str[i] == str[k])
{
str[k] = '\0';
}
}
}
for (int i = 0; i < len; i++)
{
if (str[i] != '\0')
{
printf("%c", str[i]);
}
}
return 0;
}
第二种方法:空间换时间
由于常见的字符只有256个,可以假设此题字符串不同的字符个数最多为256个,那么可以申请一个大小为256的int类型的数组纪录每个字符出现的次数,初始化都为0,把这个字符的编码作为数组的下标,在遍历字符数组时,如果这个字符出现的次数为0,那么把它置为1;如果这个字符出现的次数为1,说明这个字符在前面已经出现过了,可以把这个字符置为’\0’,就实现了去重的目的。这种方法只需要进行一次遍历,时间复杂度为O(n),但是需要额外申请256大小的空间。
方法三:新建数组写入排序
将数组中a不重复的字符放进数组b中,再对数组b输出。
//代码展示助于理解for(int i=0;i<strlen(a);++i){
int k;
for(k=0;k<i;++k){//注意k<i
if(a[i]==b[k]) break;
}
if(k==i){//当没有执行break时即为没有重复的字符串(核心)
b[n]=a[i];
++n;
}
}
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[10], s[10];
gets(str);
int n = 0;
int len = strlen(str);
for (int i = 0; i < len; i++)
{
int k;
for (k = 0; k < i; k++)
{
if (str[i] == str[k])
{
break;
}
}
if (i == k)
{
s[n] = str[i];
n++;
}
}
for (int i = 0; i < n; i++)
{
printf("%c", s[i]);
}
return 0;
}
方法四:对原数组排序,输出非重复字符(某些情况下用)
直接对原字符数组排序,输出不重复的字符,排完顺序后更容易去除重复的字符
(就是说先对混乱的字符串用Asall码进行排序,然后再比较前后的字符串是否相同)
#include<stdio.h>
#include<string.h>
int main()
{
char s[80];
int n;
gets(s);
n=strlen(s);
char temp;
for(int i=0;i<n;++i){ //依然是冒泡法。。。
for(int k=0;k<n-1;++k){
if(s[k]>s[k+1]){
temp=s[k];
s[k]=s[k+1];
s[k+1]=temp;
}
}
}
putchar(s[0]);
for(int i=1;i<n;++i){
if(s[i]!=s[i-1])
putchar(s[i]);
}
return 0;
}