首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

不甘呐,竟然被FOR循环难住了

2013-04-09 
不甘心呐,竟然被FOR循环难住了Public Function strDelSameItemInArr(ByVal strArray As String()) As Stri

不甘心呐,竟然被FOR循环难住了

    Public Function strDelSameItemInArr(ByVal strArray As String()) As String()
        Dim I As Long, J As Long, K As Long, mCount As Long
        mCount = UBound(strArray)
        For I = 0 To mCount - 1
            For J = I + 1 To mCount
                If strArray(I) = strArray(J) Then
                    For K = J To mCount - 1
                        strArray(K) = strArray(K + 1)
                    Next K
                    ReDim Preserve strArray(mCount - 1)
                    mCount = mCount - 1
                    If J = mCount Then
                        Exit For
                    End If
                End If
            Next
        Next
        Return strArray
    End Function


功能是要删除数组中的重复项
Dim strArray As String() = {"start18", "start36", "start54", "start18", "start18"}


调试发现执行过一次mCount = mCount - 1后mCount=3,而再继续NEXT后J已经是4了,
但是
For J = I + 1 To mCount竟然还能执行,导致 strArray(J)下标超限

不解 FOR
[解决办法]
很多人觉得VB6简单,还打比方,说VB好比公共汽车,而VB.NET好比“喷气客机”——他们根本不了解的是,喷气客机的飞行员可以在巡航的时候睡觉的哦,BUS司机一边开车一边吃泡面就被人骂了。

我们看看在VB.NET中实现你的这个需求需要几行代码:

Public?Function?strDelSameItemInArr(ByVal?strArray?As?String())?As?String()
????Return strArray.Distinct().ToArray()
End?Function

[解决办法]
“但是 For J = I + 1 To mCount 竟然还能执行,导致 strArray(J)下标超限”
  这个没什么好奇怪的,For J = I + 1 To mCount中控制变量的终值,在执行到这句时,已经由mCount的值决定了,你在后面的代码中改变mCount的值,并不会改变这个For循环的执行次数。

对于楼主的代码,简单修正如下:
'Public Function strDelSameItemInArr(ByVal strArray As String()) As String()
'原代码错误:①格式错误;②调用规范错误(数组只能ByRef)。


Public Function strDelSameItemInArr(strArray() As String) As String()
   Dim I As Long, J As Long, K As Long, mCount As Long
   '**************************
   Dim arrTemp() As String
   Dim strTemp$
   '**************************
   arrTemp = strArray
   mCount = UBound(strArray)
   For I = 0 To mCount - 1
      'For J = I + 1 To mCount
      '   If strArray(I) = strArray(J) Then
      '      For K = J To mCount - 1
      '          strArray(K) = strArray(K + 1)
      '      Next K
      '      ReDim Preserve strArray(mCount - 1)
      '      mCount = mCount - 1
      '      If J = mCount Then
      '          Exit For
      '      End If
      '   End If
      'Next
      strTemp = arrTemp(I)
      '用于比较的‘基准串’用简单变量,可以提升运行速度
      J = I + 1
      '下面这段‘筛选’过程,比你原来的方式速度要快得多
      Do
         If (strTemp = arrTemp(J)) Then
            arrTemp(J) = arrTemp(mCount)
            mCount = mCount - 1
         Else
            If (mCount = J) Then Exit Do
            J = J + 1
         End If
      Loop
      If (mCount = I + 1) Then Exit For
   Next
   ReDim Preserve arrTemp(mCount)
   'Return strArray   '语法错误
   strDelSameItemInArr = arrTemp
End Function


注意这个修改后的代码,会改变字符串数组的元素顺序。
如果不允许改变顺序,则可以用‘索引表’的方法来解决。

  另外给楼主的建议是,如果数据量比较大,最好还是通过 Dictionary 或 Collection 对象来‘筛选’,比你自己用循环来进行字符串比较要快些,并且过程也简单、清晰些。

[解决办法]
本帖最后由 bcrun 于 2013-03-28 11:59:03 编辑 二楼分析的对,毛病就出在循环的上限是开始时就固定了的。在循环内更改循环上限是无效的。

一个绕过的办法就是递减循环,因为循环计数器是可以动态改动的。下面是 VB6.0 代码:



Public Sub strDelSameItemInArr(ByRef strArray() As String)
    Dim I As Long, J As Long, K As Long, mCount As Long


    mCount = UBound(strArray)
    For I = mCount To 1 Step -1
        For J = I - 1 To 0 Step -1
            If strArray(I) = strArray(J) Then
                For K = I To mCount - 1
                    strArray(K) = strArray(K + 1)
                Next K
                mCount = mCount - 1
                ReDim Preserve strArray(mCount)
                
                I = I - 1
            End If
        Next
    Next
End Sub


[解决办法]


每多学一点知识,就少写一行代码。

热点排行