[英]Sort array numerically, with strings and integers
我有一个数组,数组旁边有一个名称和一个分数,我需要将其从高到低排序。 我已经按字母顺序对其进行了排序。
Dim reply3 As String
Dim name As String
Dim score As Integer = 0
Dim classnum As Integer
Dim filePath As String
Dim reply As Integer
Dim reply2 As Integer
Dim strline As String
Dim array() As String
Sub Main()
Console.Title = "Math Test"
Console.WriteLine("Do you want to start the test or view previous results? Press 1 for test, 2 for results")
reply = Console.ReadLine
If reply > 2 Then
MsgBox("Invalid Reply Press Ok to end")
End
End If
If reply = 2 Then
Console.WriteLine("What class do you want to see the results of? 1, 2, or 3?")
reply2 = Console.ReadLine()
End If
If reply2 > 3 Then
MsgBox("Invalid Reply Press Ok to exit")
End
End If
Select Case reply2
Case 1
Dim results1 As String = File.ReadAllText("Z:\scores class 1.txt")
array = Split(results1, "-")
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
Console.WriteLine("Would you like these to be sorted? Press 1 for yes, 2 for no")
If Console.ReadLine = 1 Then
System.Array.Sort(array)
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
ElseIf Console.ReadLine = 2 Then
End
End If
Console.ReadLine()
Case 2
Dim results1 As String = File.ReadAllText("Z:\scores class 2.txt")
array = Split(results1, "-")
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
Console.WriteLine("Would you like these to be sorted? Press 1 for yes, 2 for no")
If Console.ReadLine = 1 Then
System.Array.Sort(array)
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
ElseIf Console.ReadLine = 2 Then
End
End If
Console.ReadLine()
Case 3
Dim results1 As String = File.ReadAllText("Z:\scores class 3.txt")
array = Split(results1, "-")
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
Console.WriteLine("Would you like these to be sorted? Press 1 for yes, 2 for no")
If Console.ReadLine = 1 Then
System.Array.Sort(array)
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
ElseIf Console.ReadLine = 2 Then
End
End If
Console.ReadLine()
End Select
If reply = 1 Then
Console.WriteLine("What is your name?")
name = Console.ReadLine
Console.WriteLine("What class are you in, 1, 2 or 3?")
classnum = Console.ReadLine
If classnum < 1 Then
MsgBox("Invalid Class number")
End
ElseIf classnum > 3 Then
MsgBox("Invalid Class number")
End
End If
Console.WriteLine("What is 9+10 ?")
If Console.ReadLine = 19 Then
score += 1
End If
Console.WriteLine("What is 5x10 ?")
If Console.ReadLine = 50 Then
score += 1
End If
Console.WriteLine("What is 122÷2 ?")
If Console.ReadLine = 61 Then
score += 1
End If
Console.WriteLine("What is 424 + 10 ?")
If Console.ReadLine = 434 Then
score += 1
End If
Console.WriteLine("What is 234 x 3 ?")
If Console.ReadLine = 702 Then
score += 1
End If
Console.WriteLine("What is 10 x 10 ?")
If Console.ReadLine = 100 Then
score += 1
End If
Console.WriteLine("What is 12 x 64 ?")
If Console.ReadLine = 768 Then
score += 1
End If
Console.WriteLine("What is the value of N in this equation? 2n+6=10?")
If Console.ReadLine = 4 Then
score += 1
End If
Console.WriteLine("What is 9 x 73 ?")
If Console.ReadLine = 657 Then
score += 1
End If
Console.WriteLine("What is 1 + 1 ?")
If Console.ReadLine = 2 Then
score += 1
End If
MsgBox("Your score was " & score & " Click ok to finish.")
Dim output1 As String = name & " " & score & "-"
Select Case classnum
Case 1
filePath = System.IO.Path.Combine(
My.Computer.FileSystem.SpecialDirectories.MyDocuments, "scores class 1.txt")
My.Computer.FileSystem.WriteAllText(filePath, output1, True)
Case 2
filePath = System.IO.Path.Combine(
My.Computer.FileSystem.SpecialDirectories.MyDocuments, "scores class 2.txt")
My.Computer.FileSystem.WriteAllText(filePath, output1, True)
Case 3
filePath = System.IO.Path.Combine(
My.Computer.FileSystem.SpecialDirectories.MyDocuments, "scores class 3.txt")
My.Computer.FileSystem.WriteAllText(filePath, output1, True)
End Select
End If
End Sub
我需要称为数组的数组进行数字排序。 我将为用户添加选项,以便用户按字母顺序选择是否要进一步排序。
字符串不是数字。 它们是文本。
在字符串格式中,它们只是字符( 数字 ),它们不是也不 将按数字排序:
Dim myVals As String() = {"5", "07", "178", "9", "899", "42", "3"}
' add two of the "numbers"
Console.WriteLine("{0} + {1} = {2}", myVals(0),
myVals(1), (myVals(0) + myVals(1)))
Array.Sort(myVals)
Array.Reverse(myVals)
For Each s As String In myVals
Console.Write("{0} ", s)
Next
输出:
5 + 07 = 507
9 899 5 42 3 178 07
值未按预期添加,因为它们不是数字。 取而代之的是,代码仅将字符串的两位连接在一起(粘合在一起)。 数组内容也按字符排序。 排序时, "9"
将始终被视为大于其他值。
这也适用于以字符串形式存储的日期。 “ 9/16/1914”将始终大于/晚于“ 12/1/2015”。
因为作为文本,所以按字典顺序或字母顺序使用(0,1,2,3,4,5,6,7,8,9)。
数字以字符串形式存储,失去其数值(直到转换)。 "9"
高于种"899"
,因为"9"
高于 "899"
。 “ Able”和“ Baker”将基于“ A”和“ B”进行排序的方式相同。 由于zed, "07"
排序最低。 数值被忽略,因为它们是字符串(文本)。
字符串“ dates”也是如此-它们不是日期,也没有日期值。 您的大脑会根据模式将它们解释为日期。 在计算机上,它们仍然是文本,并且"9/16/yyyy"
计算结果将大于"12/1/yyyy"
。
现在我们知道字符串数组中没有整数,只有数字。 但是,如果您有2个数据,则要单独使用它们,则需要分别存储它们。 类是理想的选择:
Public Class Student
Public Property Name As String
Public Property Score As Integer
Public Sub New()
End Sub
' overload
Public Sub New(n As String, s As Integer)
Name = n
Score = s
End Sub
Public Overrides Function ToString() As String
Return String.Format("{0} ({1})", Name, Score)
End Function
End Class
请注意,名称和分数存储为正确的数据类型,这将使代码将分数用作数字值。 与使用2个数组不同,该名称不能与乐谱分离。
还请注意, ToString()
允许我们根据需要显示数据。 仅仅因为我们想显示名称和分数并不意味着我们必须将这些信息粘合在一起。 样本输出:
查理(89)
放弃您的数组(和ArrayList)! 这是21世纪,我们有Typed集合(称为Generics ):
Private Students As List(of Student) ' declaration
Students
是一个只能存储Student
对象的集合,而Student
对象又包含2个数据。 让我们添加一些:
Students = New List(Of Student) ' create List instance
Dim stud As New Student ' create new student
stud.Name = "Harvey" ' set props
stud.Score = 72 ' 72 is a NUMBER
Students.Add(stud) ' add to collection
' fast way, using the overload, no temp student object needed
Students.Add(New Student("Bob", 67))
Students.Add(New Student("Hoover", 82))
Students.Add(New Student("Ziggy", 97))
...
Students.Add(New Student("Zoey", 89))
请注意,我们不必设置List(of Student)
的大小-它会根据需要增加。 您仍然可以按元素/位置引用它们: Students(0)
是Student
对象, Students(0).Name
将是第一个位置(“ Harvey”)中学生的名称。
Students = Students.OrderByDescending(Function(x) x.Score).ToList()
这将以所需顺序创建一个新集合。 按名称对匹配分数进行排序:
Students = Students.OrderByDescending(Function(x) x.Score).
ThenBy(Function(q) q.Name).ToList()
' print the contents:
For Each st As Student In Students
Console.WriteLine(st)
Next
加上多个匹配分数89
后的结果:
齐吉(97)
查理(89)
回声(89)
探戈(89)
佐伊(89)
胡佛(82)
哈维(72)
鲍勃(67)
要跟踪多个班级成绩(在代码中的提示),您可以向班级添加一个Id
(1,2,3)或Code
(“ 101”,“ 201”,“ 303”)以限定哪个班级,系列或设置每个用户分数所属的。 使用上面的其他.Where()
仅获得主列表的一个子集。
最后,与其将分数集存储到单个文件中,不如将其当前状态的整个列表序列化并保存为3或4行代码。
字符串不包含数字,也不包含Dates 。 它们是文本。
如果要单独使用单个数据元素,请不要将其存储为一个。
实际上,您所拥有的是一个包含多种数据类型的多维数组(但在您的情况下,您已将每一行连接到一个字符串中)。 没有一种万能的方法来处理这种情况,但是这里有一些需要考虑的方法:
一个多维对象数组:
Dim array(,) As Object = {{"Student1", 95},{"Student2", 87}...}
两个平行的一维数组:
Dim names() As String = {"Student1","Student2"...}
Dim scores() As Integer = {95, 87...}
创建一个类或结构:
Public Class Student
Property name As String
Property score As Integer
End Class
这些通常都是更好的存储数据的方法,但通常会给您增加对数据进行排序的负担。 这导致我最终选择...
共同解决一个变通方法:
本质上,这就是您已经完成的操作-将字符串与整数连接起来,以允许使用内置的Sort
过程。 您可以使用相同的技巧按分数排序,但是如果希望整数正确排序,则必须将其0填充。 请参阅下面的代码,但是您已经得到警告:这类解决方案在短期内始终易于实现,但从长远来看却变得笨拙且用处不大,通常需要替换为上面的“更好”的解决方案之一。
Private Sub FlipStrings(ByRef students() As String)
If students Is Nothing Then Exit Sub
For i As Integer = 0 To UBound(students)
Dim parts() As String = Split(students(i))
If parts Is Nothing OrElse UBound(parts) <> 1 Then Continue For
If IsNumeric(parts(0)) Then
students(i) = parts(1) & " " & CInt(parts(0))
ElseIf IsNumeric(parts(1)) Then
Do Until len(parts(1)) = 3 'Assuming max score of 100'
parts(1) = "0" & parts(1)
Loop
students(i) = parts(1) & " " & parts(0)
End If
Next
End Sub
我写了这个,所以您仍然可以像以前一样存储和显示数组。 现在,按分数排序
FlipStrings(array)
System.Array.Sort(array)
FlipStrings(array)
应该给您您想要的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.