Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
楼主: 爱疯

[已解决]在一个字符串中找到第一个只出现一次的字符(不用字典)

[复制链接]
发表于 2013-9-10 23:49 | 显示全部楼层
其实这题有字典做,并没有什么优势。我想了下,用字典去判断第一个出现的非重复的,并没有简单。
回复

使用道具 举报

 楼主| 发表于 2013-9-10 23:52 | 显示全部楼层
本帖最后由 爱疯 于 2013-9-11 00:03 编辑

5楼的也很好理解。个人觉得,就是代价有点大{:301:}
不过,每个思路都有它自己的特点
回复

使用道具 举报

 楼主| 发表于 2013-9-11 00:07 | 显示全部楼层
本帖最后由 爱疯 于 2013-9-11 00:10 编辑

学习6楼,一下给出3种风味:

t1比较正反读取的位置。
t2利用如果不重复,替换后就只会减少1位的特点。
t3利用split分隔的特点,判断数组元素的个数。



Sub t1()
    s$ = "abaccdeff"
    Do While i <= Len(s)
        i = i + 1
        t = Mid(s, i, 1)
        m = InStr(s, t)
        n = InStrRev(s, t)
        If m = n Then MsgBox t: Exit Sub
    Loop
    MsgBox "no"
End Sub
还是用点变量吧,我不这样就会晕{:031:}。
当然m,n一般不会设,只不过这里是为了快速理解。
回复

使用道具 举报

 楼主| 发表于 2013-9-11 00:16 | 显示全部楼层
冠军欧洲2010 发表于 2013-9-10 23:19
凑个热闹

坐等请疯神点评

我只是来学习大家的好办法,一起学习哈

和6楼t1相同,但少了判断如果没有单独字符串的。
回复

使用道具 举报

 楼主| 发表于 2013-9-11 00:19 | 显示全部楼层
wp8680 发表于 2013-9-10 23:49
其实这题有字典做,并没有什么优势。我想了下,用字典去判断第一个出现的非重复的,并没有简单。

我是想,一提重复方面的问题,可能立刻会想到用字典,

就会偷懒,不再考虑有没有别的好办法。

回复

使用道具 举报

 楼主| 发表于 2013-9-11 07:48 | 显示全部楼层
本帖最后由 爱疯 于 2013-9-11 07:51 编辑

我觉得6楼第2种就好了。这和它一样。不同的是
1)用定循环
2)字符串长度逐渐减小
一方面,觉得开销更小;一方面觉得区别和意义真的不大,反而没6楼2简洁



Sub test()
    Dim Str$, t$, n, i, p, q

    Str = "aa"
    n = Len(Str)

    For i = 1 To n
        p = Len(Str)    '之前
        If p = 0 Then Exit For
        
        t = Left(Str, 1)
        Str = Replace(Str, t, "")
        
        q = Len(Str)    '之后
        If p = q + 1 Then Exit For
    Next i

    If p + q = 0 Then MsgBox "没有"
    If i > n Then MsgBox t
End Sub

回复

使用道具 举报

发表于 2013-9-11 09:15 | 显示全部楼层    本楼为最佳答案   
本帖最后由 leolee82 于 2013-9-11 09:17 编辑

只对英文有效,用了HASH的方法
  1. '只对英文有效,用了HASH的方法
  2. Sub t()
  3. s = "adfsafgd"

  4. Dim arr(65 To 122) As Byte
  5. Dim b() As Byte
  6. b = StrConv(s, vbFromUnicode) ' 字符串转成数组

  7. '找出只出现一次的字符
  8. For i = 0 To UBound(b)
  9.     Select Case arr(b(i))
  10.         Case 0: arr(b(i)) = 1   '只出现一次
  11.         Case 1: arr(b(i)) = 255 '出现多次
  12.     End Select
  13. Next

  14. '找出上面结果中第一次出现的字符
  15. Dim ipos As Long, iPosMin As Long
  16. ipos = -1
  17. For i = LBound(arr) To UBound(arr)
  18.     If arr(i) = 1 Then
  19.         '这里用InStrRev比InStr速度要快,因为搜索范围会不断减少
  20.         ipos = InStrRev(s, Chr(i), ipos, vbBinaryCompare)
  21.         If ipos Then iPosMin = ipos
  22.     End If
  23. Next
  24. End Sub
复制代码
回复

使用道具 举报

发表于 2013-9-11 09:24 | 显示全部楼层
{:3912:}这个要是用"C"来写太简单了{:3912:}

点评

为什么c会太简单呀?  发表于 2013-9-11 10:06
回复

使用道具 举报

发表于 2013-9-11 09:31 | 显示全部楼层
Sub t4()
s$ = "abcddacde"
Do While i% < Len(s)
   i = i + 1
   st = Mid(s, i, 1)
   Mid(s, i, 1) = " "
   If InStr(s, st) < 1 Then Exit Do
   s = Replace(s, st, "")
   st = ""
Loop
If st <> "" Then MsgBox st
End Sub
t4除了mid外,对此问题毫无意义。

确实这问题用字典要麻烦得多

学习17楼的StrConv,但还是未窥门径
回复

使用道具 举报

 楼主| 发表于 2013-9-11 09:51 | 显示全部楼层
leolee82 发表于 2013-9-11 09:15
只对英文有效,用了HASH的方法

谢谢82!
我不懂哈希算法,很想认识一下。17楼的语法好理解,但为什么要这样我就不知道了。
以这题来说,可否简单讲解 下,为何要这样写呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-6-18 09:08 , Processed in 0.265062 second(s), 10 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表