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

求1排序函数

2013-12-28 
求一排序函数有一列表内数据如下1.JPG4.JPG22.JPG3.JPG8.JPG11.JPG16.JPG2.JPG。。。如何将这类的数据进行排

求一排序函数
有一列表内数据如下
1.JPG
4.JPG
22.JPG
3.JPG
8.JPG
11.JPG
16.JPG
2.JPG
。。。

如何将这类的数据进行排序呢。
[解决办法]
本帖最后由 bcrun 于 2013-07-23 16:10:14 编辑

Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long 
' 生成数据到一个文本文件
Private Sub Command1_Click()
    Dim test As String
    Dim i As Long
Dim savetime As Long
savetime = GetTickCount
    Open App.Path & "" & Text1.Text For Output As #1
    For i = 1 To 100000
        test = String(8 - Len(Hex(i)), "0") & Hex(i)
        Print #1, test
    Next i
    Close #1
MsgBox "耗时:" & GetTickCount - savetime & " 毫秒"
End Sub
' 读取文本文件的每一行数据对其进行排序输出
Private Sub Command2_Click()
    Dim ReadArray() As String
    Dim lngArraySize As Long
    Dim strTmp As String
    Dim fs As Integer
    Dim row As Long
    Dim i As Long
    Dim j As Long
    Dim index As Long
    Dim IsCompositor As Boolean
Dim savetime As Long
savetime = GetTickCount
    '========== 把文本文件以行为单位读入字符串数组 ==========
    row = 0
    ReDim ReadArray(row)
    fs = FreeFile
    Open App.Path & "" & Text1.Text For Input As #fs
    Do While Not EOF(fs)
    Line Input #fs, strTmp
    ReadArray(row) = strTmp
    row = row + 1
    ReDim Preserve ReadArray(row)
    Loop
    Close #fs
    lngArraySize = row - 1
    ReDim Preserve ReadArray(lngArraySize)
     
    '========== 对数组进行排序 ==========
    '快速法
    Call compositor_quick(ReadArray, 0, lngArraySize)
     
    '========== 将排序好的数组输出 ==========
    For i = 0 To lngArraySize
        List1.AddItem ReadArray(i)
    Next i
Dim overtime As Long
overtime = GetTickCount
MsgBox "耗时:" & GetTickCount - savetime & " 毫秒"
End Sub
' 数组排序函数
Private Sub compositor_quick(strArray() As String, i As Long, j As Long)
    Dim m As Long, _
        n As Long, _
        temp As String, _
        strTmp As String
    m = i
    n = j
    strTmp = strArray((m + n) / 2)
    Do
        ' 从左到右找比k大的元素
        Do While (strArray(m) < strTmp And m < j)
            m = m + 1
        Loop
        ' 从右到左找比k小的元素
        Do While (strArray(n) > strTmp And n > i)
            n = n - 1
        Loop
        If m <= n Then


            ' 若找到且满足条件,则交换
            temp = strArray(m)
            strArray(m) = strArray(n)
            strArray(n) = temp
            m = m + 1
            n = n - 1
        End If
    Loop While m <= n
    If m < j Then compositor_quick strArray, m, j '/*运用递归*/
    If n > i Then compositor_quick strArray, i, n
End Sub


[解决办法]

无论什么规则,最后只不过是在过程里改点细节的问题,如数组类型为整形、日期类型,对比时的变量或大于小于条件改变一下而已,甚至是多条件分级别排序(类似SQL的排序需求),都可以这么弄出来,如文件的创建日期、文件类型、文件名等等综合条件的排序,无非就是弄个结构体,在循环时多设置几个判断条件就可以实现这种综合条件排序了,这种方法可以说适用于各种需求的排序处理,其使用的问题在于使用者是否理解这种排序方法,并能够融会贯通这种理念才好对其进行修改,如果还有问题就是实用的算法是否够快的问题,但经过测试,效率基本上还是能接受的。当然,这种过程也可以进一步封装,使得使用者可以很简单的对多条件数据进行排序,比如使用二维数组,然后加个优先级别参数,如:

Redim Files(1,3)
Files(0,0) = "4.jpg"
Files(0,1) = #2013-7-21 00:58:00#
Files(0,2) = "jpg"
Files(0,3) = 3000000
Files(1,0) = "2.jpg"
Files(1,1) = #2013-7-21 00:58:00#
Files(1,2) = "jpg"
Files(1,3) = 132701
' 调用排序过程
Call CompositorArray(Files,"2:asc,1:desc,0:asc,3:asc")
...
' 定义排序函数
Sub CompositorArray(ByRef arr() as Variant,ByVal PRI As String)
...
End Sub

这样一来这种过程的可重用性就会很强,实用性也很高,而且效率可以自己掌控(看自己的算法啦)。更为重要的是这是一种技术,而不是用某种工具,这种技术可以跨语言、跨平台的使用,我在做以前的一个单片机项目中就用过这种技术,主要处理任务队列,可以说解决了很大的问题,只不过单片机上的过程就没有 CompositorArray 这种结构复杂,是根据具体需求改出来的排序过程。
[解决办法]

Private Sub Command6_Click()
    Dim DriverObject As Object, _
        FileObject As Object, _
        fObject As Object, _
        NowPath As String, _
        FileArray() As String, _
        FileCount As Long, _
        TempName As String, _
        TempTime As Date, _
        i As Long, _
        j As Long, _
        is_compositor As Boolean
    List1.Clear
    NowPath = App.Path
    ' 用 fso 查询路径得到指定路径下的文件
    Set DriverObject = CreateObject("Scripting.FileSystemObject")
    If DriverObject.FolderExists(NowPath) Then
        Set FileObject = DriverObject.GetFolder(NowPath).Files
        FileCount = FileObject.count
        ReDim FileArray(FileCount - 1, 1)
        i = 0
        For Each fObject In FileObject
            FileArray(i, 0) = fObject.Name
            FileArray(i, 1) = fObject.DateLastModified
            i = i + 1
        Next
        Set FileObject = Nothing
    End If
    If FileCount >= 1 Then
        ' 简单的冒泡法排序,效率很低,不过作为数据不多的文件处理够用了,最主要的是容易理解
        For i = 0 To FileCount - 1
            For j = 0 To FileCount - 1
                If Len(FileArray(i, 0)) < Len(FileArray(j, 0)) Then
                    is_compositor = True
                Else
                    If FileArray(i, 0) < FileArray(j, 0) Then
                        is_compositor = True


                    Else
                        is_compositor = False
                    End If
                End If

                If is_compositor Then
                    TempName = FileArray(j, 0)
                    TempTime = FileArray(j, 1)
                    FileArray(j, 0) = FileArray(i, 0)
                    FileArray(j, 1) = FileArray(i, 1)
                    FileArray(i, 0) = TempName
                    FileArray(i, 1) = TempTime
                End If
            Next
        Next
        For i = 0 To FileCount - 1
            List1.AddItem FileArray(i, 0)
        Next
    End If
End Sub


[解决办法]
类似楼主这样的问题,我在2006年给我的好友做的,用VBA处理Excel报表时就遇到了。
我就是根据需求,把它分成了3个类别,分别排序后输出。
但排序依据就复杂得多了,先根据分出的“类别”,再按“3到5个列”中的数据值,来决定哪个排在前、哪个排在后,这样才形成了一个规范、清晰的报表。
说实在的,她们之前用Excel的数据透视表弄出来的报表,我看着都烦。那个内容之乱哦……没话说
  单说那个包含数值的字符串,楼主的仅是“一段”,我那个要处理的是分成3段的,并且第2、第3段分别再可以分为:1个数值,和用/隔开的两个数值 这两种(数值也是有整数和带小数点的数,当然这不算问题)。

正如SupermanKing说的那样,只要知道如何排序,再复杂的排序也不是问题。

[解决办法]
说个思路,
1、建立数组存入文件名
2、求最长文件名的长度N
3、用Format将文件名前边补0,然后排序
4、去除前边添加的0

热点排行