算法题:在一个字符串中找到只出现一次的字符。如输入abaccdeeff,则输出bd。

今天的算法学习还是和字符串有关,这个题目据说是以前的某公司面试的笔试题目。题目意思就是说,在一个字符串中找到只出现了一次的那些字符,并且输出来。

作为非IT的我,平时使用Matlab比较多。不是科班出身,对于这个题目的理解可能也比较简单。但是也算是一个算法的锻炼吧,每天进步一点。一个更主要目的就是养成记录的习惯,积少成多。

不多说直接上我写的matlab代码吧

常规算法 Matlab:常规遍历

clc
clear
close all
strInput='abaccdeeff';
strLength=size(strInput,2);
if strLength==0
    disp('this string is null !')
end
marker=ones(1,strLength);
count=0;
letterAppearedOnce=[];
for i=1:strLength
    flag=1;
    if marker(i)
        for j=i+1:strLength
            if strInput(j)==strInput(i)
                flag=0;
                marker(j)=0;
                %break;
            end
        end
    else
        flag=0;
        continue;
    end
        if flag
        count=count+1;
        letterAppearedOnce=[letterAppearedOnce,strInput(i)];
    end     
end
if count==0
    disp('there is not letter appearing once ')
elseif count==1
    disp(['these is only ',num2str(count),' letter appearing once !','this letter is ',letterAppearedOnce]);
else
    disp(['these are ',num2str(count),' letters appearing once !','there letters are ',letterAppearedOnce]);
end

这个写的比较繁琐,我的思想就是主要遍历去比较吧,这里marker数组和flag变量比较重要。marker数初始时里面全是1,如果遍历比较的时候,出现了相同的,那么那个相同的字符的索引对应的marker数组的值为0,例如,
i=1时,遍历比较剩余的字符
j=3时,发现相同的字符,这marker(3)=0
这样的话第一层循环到i=3时,判断一下marker(3)是否为真,不是则停止此次循环,进行下一次循环。

flag变量确定了是否存在出现一次的字符。flag=1,存在,flag=0,不存在。

输出结果为:

These are 2 letters appearing once !there letters are:
bd

可以看出来,结果没有问题!把marker数组的结果贴出来

1   1   0   1   0   1   1   0   1   0

再换一个输入:

strInput='abaccddeeff';

得到的结果为:

There is only 1 letter appearing once !this letter is:
b

同样还是贴出marker数组:

1   1   0   1   0   1   0   1   0   1   0

再换一个输入,重复的字符在2个以上:

strInput='abacacddeccefeeff';

此时的结果为:

these is only 1 letter appearing once !this letter is:

b

marker数组为:

1   1   0   1   0   0   1   0   1   0   0   0   1   0   0   0   0

这种算法比较的简单,而且比较的复杂,下面是一种简单的方法,思想比较好。

一种好的算法:利用字符ASCII码实现

因为每个字符都有一个ASCII码,所以可以定义一个用于记录字符出现次数的数组,用字符的ASCII码做为数组的下标,当遍历字符

串时,就给相应下标对应的字符次数加1。这样对字符串的一次遍历就能记录每个字符出现的次数。再找到次数为的1的索引,即

字符出现一次的字符的 ASCII

clc
clear
close all
strInput='abaccdeeff';
strLength=size(strInput,2);
if strLength==0
    disp('this string is null !')
end
strAscll=zeros(1,256);
for i=1:strLength   strAscll(abs(strInput(i)))=strAscll(abs(strInput(i)))+1;
end
char(find(strAscll==1))

输出结果为

    ans =
    bd

这种算法十分的简单明了!几乎就是一个遍历,其他的判断全部都没有。最后得到的结果就是这么的完美!

Python 3 实现:字典数据结构的利用

Python3 的字典这种数据结构还是比较好的,原理就不多说了,直接看代码就能体会到这个得妙处:

def find_once_appear_letter(string):
    d={}
    onceAppearLetter=''
    for i in string:
        d[i]=d.get(i,0)+1
    for item in d.items():
        if item[1]==1:
            onceAppearLetter+=item[0]
    return onceAppearLetter

if __name__ == "__main__":
    str='abaccdeeff'
    print('The string is :\n')
    print(str)
    print()
    print('the letters appearing only once are:\n') 
    print(find_once_appear_letter(str))

结果为:

这里写图片描述


完美,学无止境!


艾勇 上海交通大学
2017/7/27

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值