| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2627 人关注过本帖
标题:请教把list转变成数组并处理数据的问题。
只看楼主 加入收藏
ictest
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:333
专家分:114
注 册:2010-2-17
结帖率:70%
收藏
已结贴  问题点数:10 回复次数:8 
请教把list转变成数组并处理数据的问题。
程序代码:
Dim a() As String
Open (Dir1.Path & "\330000-04.csv") For Input As #1
        Do While Not EOF(1)
        Line Input #1, temp1
       
If IsNumeric(Mid(temp1, 1, 1)) = True Then
a = Split(temp1, ",")
List2.AddItem a(3) & "-" & a(4) & "-" & a(5)
End If
Loop
Close #1

DoEvents

Dim i As Single, j As Single
Dim ListArr() As String
Dim Repeat As Boolean
ReDim ListArr(0)
Dim x() As String
Dim y() As String
ListArr(0) = List2.List(List2.ListCount - 1)
For i = List2.ListCount - 1 To 0 Step -1
x = Split(List2.List(i), "-")
    Repeat = False
    For j = 0 To UBound(ListArr)
    y = Split(ListArr(j), "-")
            If ("-" & x(1) & "-" & x(2)) = ("-" & y(1) & "-" & y(2)) Then Repeat = True: Exit For
    Next
    If Repeat = False Then
        ReDim Preserve ListArr(UBound(ListArr) + 1)
        ListArr(UBound(ListArr)) = List2.List(i)
    End If
Next
List2.Clear
For i = UBound(ListArr) To 0 Step -1
    List2.AddItem ListArr(i)
Next
以上是我的程序里一段处理list2中重复数据的程序,目的是从后向前查找list2中部分字符串重复的,用后面的替换前面重复的。整段程序运行没有错误。
现在我遇到两个问题:
1、list控件有数量限制,大概3万2千多数据后ListCount就变成负数了。但我的数据最多有10万条左右。我想把数据读入内存数组,然后再处理,那么这段程序怎么修改呢?
麻烦哪位能在这个程序的基础上进行修改后再给贴上来,谢谢!
2、整段程序运行时间较长,我大概1万7千条数据,处理了大概好几分钟,主要就是后面处理重复数据的那一段程序耗时太长,至少占用了95%的时间,有没有办法加快处理速度呢?如果要重写,怎么写呢?
附实验数据:
330000-04.rar (44.79 KB)



[此贴子已经被作者于2019-2-21 23:10编辑过]

搜索更多相关主题的帖子: list 处理 数据 Dim For 
2019-02-21 23:04
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:4 
通过分析你的数据,后三个数可以合成一个8位10进制数,可用一个long型数组存储,因此可用3种方式处理:
1,定义一个200000大小的long型数组,每读入一个数转换后和前面比较,数据比较速度比字符串比较速度快多了
2,定义一个1000000大小的byte型数组,使用开关模式比较,还能自动排序,速度比1快
3,使用数据库,利用sql语句自动过滤,速度应该不慢。

能编个毛线衣吗?
2019-02-22 11:03
ZHRXJR
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:125
帖 子:1034
专家分:5519
注 册:2016-5-10
收藏
得分:4 
目的是从后向前查找字符串重复的,用后面的替换前面重复的。
图片附件: 游客没有浏览图片的权限,请 登录注册

如果有指定的列不重复,我认为应该不是很复杂。

请不要选我!!!
2019-02-22 19:25
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:336
专家分:1135
注 册:2014-4-13
收藏
得分:4 
列表框是用于向用户显示数据的,处理数据不应该从这里获取数据,处理数据在内存中进行,数据从文件中取得,vb有一个字典容器,能够存储“键--值”对,存储时可以检测重复的键值,能够达到去重的目的,10万条数据从文件中存入字典中是很快的,再说列表框显示数据,10万或1万条数据完全用列表框显示是没有必要的,人是不能一次接受这么多的数据的,每次显示几十条数据,设置一个翻屏按钮或滚动条,进行翻屏或滚屏显示,这样显示速度也很快,否则10万条数据即使列表框能够容下,显示出来也让人等的心烦的,当处理数据的规模很大时,一些常用的方法就应该慎用,比如 & 操作符,Split()函数 ReDim Preserve ListArr(UBound(ListArr) + 1)这样的操作,这些用的多了,处理速度很难达到要求。
2019-02-22 21:25
ictest
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:333
专家分:114
注 册:2010-2-17
收藏
得分:0 
*  回复wmf2014版主,感谢您的回复。您说的方法肯定很对,但我不得其法,不是很会操作。



*  回复ZHRXJR版主,感谢您的回复。我说明一下,每一行的5个数值,我只用到了后三个,所以用了
a = Split(temp1, ",")
List2.AddItem a(3) & "-" & a(4) & "-" & a(5)
语句,a(3)是状态类型;a(4)是X坐标;a(5)是Y坐标。也就是说每个坐标点上的状态类型不一样,从16169行开始到最后,坐标(a(4),a(5))与前面是有重复的,前面的a(3)状态有的发生改变,有的没有改变。但我不管改没改变,从后面开始提数据向前检查,当检查到前面数据的坐标(a(4),a(5))一致,就删掉前面重复的,保留后边的a(3)-a(4)-a(5)。
不知道我这样解释您是否明白了?


*  回复jklqwe111坛友大神,谢谢您的回复,您说的很对,这些数据控件在大数据前,就会表现的很不尽人意,所以我一直想用内存数组的方法处理大数据,铁定会快很多,但是不太会用数组,一直很头痛。



*  经过多方的查找资料,我把程序进行了修改,尽可能的用上内存数组,运行后速度是快了很多,大概快了几倍吧,但还是需要55秒左右,不知道怎样还能快,恳求哪位能在这个新程序的基础上进行修改后再给贴上来,让我学习学习。
程序代码:
Private Sub Command1_Click()
tt = Timer

Dim strline As String
Dim a()
Dim b()
Dim XY As Long
Dim i, j, k, l As Long
Open (App.Path & "\TOBT330000-04.csv") For Input As #1
        Do While Not EOF(1)
XY = XY + 1
Line Input #1, strline
ReDim Preserve a(XY)
a(XY - 1) = strline
Loop
Close #1

Print XY & "  " & a(0)
DoEvents
For i = UBound(a) To 0 Step -1
For j = i - 1 To 0 Step -1

If Right(a(i), 8) = Right(a(j), 8) Then
a(j) = ""
End If
Next j
Next i
'比较,不为空的元素添加到新的数组中
For i = 0 To UBound(a)
If a(i) <> "" Then
ReDim Preserve b(k)
b(k) = a(i)
k = k + 1
End If
Next i
'打印输出新数组的元素

Open (App.Path & "\04.txt") For Append As #1
For i = 0 To UBound(b)
Print #1, b(i)
l = l + 1
Next i
Close #1

Print l & "  " & Timer - tt

End Sub
实验数据有改变,重新上传。
TOBT330000-04.rar (20.55 KB)
2019-02-22 22:24
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
完成你这个功能太简单了,下述代码达到你的需求不需要1秒:
程序代码:
Private Sub Command1_Click()
  Dim a(1000, 1000) As Integer   '因为你的坐标数据均小于1000,设置一个1000*1000的二维数组足够存储状态
  Dim b() As String, c As String, i As Integer, j As Integer, tt As Double
  tt = Timer
  Open (App.Path & "\TOBT330000-04.csv") For Input As #1
  While Not EOF(1)
    Line Input #1, c
    b = Split(c, ",")
    a(Val(b(1)), Val(b(2))) = Val(b(0))
  Wend
  Close #1
  Open (App.Path & "\04.txt") For Output As #1
  For i = 0 To 1000
    For j = 0 To 1000
      If a(i, j) > 0 Then Print #1, a(i, j) & "," & i & "," & j
    Next
  Next
  Close #1
  MsgBox Timer - tt

End Sub
收到的鲜花
  • abc1232812019-04-11 23:19 送鲜花  1朵  

能编个毛线衣吗?
2019-02-23 08:53
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:336
专家分:1135
注 册:2014-4-13
收藏
得分:0 
数据去重处理应该是最费时的,字典的内部是有着高效的算法的,使用也很简单,程序中应用要添加引用、

程序代码:

Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub CmdWork_Click()

  Dim strline As String
  Dim t As Long
  Dim k As Long
  Dim Data As Dictionary
  Dim vKey As Variant

  t = GetTickCount()
  
  Set Data = New Dictionary

  Open (App.Path & "\TOBT330000-04.csv") For Input As #1
  
  Do While Not EOF(1)

    Line Input #1, strline
    k = k + 1
    Data.Item(Right(strline, 8)) = strline
    
  Loop
  
  Close #1

  Open (App.Path & "\04.txt") For Append As #1
  
  For Each vKey In Data
    Print #1, Data.Item(vKey)
  Next
  
  Close #1
  
  MsgBox "intoData:  " & k & "   Data:  " & Data.Count & "   t:  " & GetTickCount() - t

End Sub
2019-02-23 12:57
ictest
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:333
专家分:114
注 册:2010-2-17
收藏
得分:0 
看看,这就是大神和屌丝,学霸和学渣的区别,身为学渣和屌丝的我,无语,只能对大神顶礼膜拜。
仔细专研了一下wmf2014版主的程序,版主使用的是二维数组吧?对坐标直接赋值,后面有重复坐标的也是直接赋值,相当于用后面的覆盖了前面的,我这样理解对吗?
jklqwe111大神的程序我还在研究学习中。。。。。

趁热打铁,继续询问更复杂一些的问题。

两个文件文件1行和文件2,内容格式都是如下:
状态-位置-X坐标-Y坐标

两个文件都是超过10万行,但文件1行数比文件2要多3万行左右。这3万行的“状态-位置-X坐标-Y坐标”都是文件2没有的。

现在要如此操作:
把文件1的每一行与文件2比较,如果这一行的“-位置-X坐标-Y坐标”部分是文件2里没有的,则跳下一行进行比较;如果这一行的“-位置-X坐标-Y坐标”部分是文件2里有的,则把文件2里包含相同“-位置-X坐标-Y坐标”部分的这一行复制到文件1里,替换原来的一行;总的来说,文件1里的“位置-X坐标-Y坐标”不能变动,原来是哪行还是哪行。

不知我这样叙述明白了吗?这样的话程序怎么写呢?
                           

[此贴子已经被作者于2019-2-23 19:26编辑过]

2019-02-23 19:21
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
这也很容易实现。
只是多了一个按文件1的顺序输出,因此定义一个三维数组“dim a(1000,1000,1) as long”即可,其中a(x,y,0)存储状态值,a(x,y,1)存储顺序值,读文件1时记录状态值和顺序值,读文件2时仅修改状态值,输出按顺序值输出即可。

能编个毛线衣吗?
2019-02-24 08:57
快速回复:请教把list转变成数组并处理数据的问题。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.065338 second(s), 11 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved