VBA 中的快速排序不会忽略字母的大小写
Quicksort in VBA does not ignore case of letters
我正在寻找一种对 VBA 中的数组进行排序的方法并找到了这个 topic
但是,此函数在大小写字母方面也有所不同。
通常单词 "also" 出现在 "apple" 之前,但是当我将此快速排序与 "also" 和 "APPLE" 一起使用时,突然 "APPLE" 排在第一位。
这是正常的吗?如果是,有没有办法忽略字母的大小写?
感谢您的帮助。
是的,这是预期的行为。在 ASCII 中,大写字母位于小写字母之前。您可以在比较周围使用 UCASE
或 LCASE
:
While (UCASE(vArray(tmpLow)) < UCASE(pivot) And tmpLow < inHi)
tmpLow = tmpLow + 1
Wend
While (UCASE(pivot) < UCASE(vArray(tmpHi)) And tmpHi > inLow)
tmpHi = tmpHi - 1
Wend
我不知道这种比较的效率如何,但我敢打赌它在长 运行 中可以忽略不计。
您可以在声明时转换 pivot 的大小写,也可以在将数组值添加到数组时转换它们。后者可能是您最好的解决方案,因为转换只发生一次。您可能已经发现 QuickSort 是一种递归算法。还不如删除每次调用必须发生的操作数。
尝试在快速排序 class/module 的顶部添加 Option Compare Text
。 (这应该是代码 all 顶部的第一行(或 Option Explicit
之后的第二行)。)
原因,当然是if因为"A"和"a"的ASCII值不一样,直接在window中做了如下证明:
? Asc("A")
65
? Asc("a")
97
你看到 "A" 出现在 "a" 之前。
现在,在引用的快速排序中,您看到他们正在使用推理比较,使用 >
或 <
类型比较器。这使用了 Ascii 值的严格比较(上图)。 Option Compare Text
将迫使 VBA 考虑 "a" = "A".
试试下面的代码,一次在添加 Option Compare Text
之前,一次在添加之后。
Public Sub test()
Debug.Print "also" < "APPLE"
End Sub
或者,您可以将快速排序修改为不区分大小写。您必须使用 StrComp
函数替换所有隐式比较器(如 <
和 >=
)——确保将 vbTextCompare
作为第三个参数.
例如:
pivot < vArray(tmpHi)
...将替换为:
StrComp(pivot, vArray(tmpHi), vbTextCompare) < 0
使用 StrComp
函数进行一些试验。乍一看似乎很奇怪,但它功能强大,而且(我相信)比普通 VBA 字符串比较更快。
我正在寻找一种对 VBA 中的数组进行排序的方法并找到了这个 topic
但是,此函数在大小写字母方面也有所不同。
通常单词 "also" 出现在 "apple" 之前,但是当我将此快速排序与 "also" 和 "APPLE" 一起使用时,突然 "APPLE" 排在第一位。
这是正常的吗?如果是,有没有办法忽略字母的大小写?
感谢您的帮助。
是的,这是预期的行为。在 ASCII 中,大写字母位于小写字母之前。您可以在比较周围使用 UCASE
或 LCASE
:
While (UCASE(vArray(tmpLow)) < UCASE(pivot) And tmpLow < inHi)
tmpLow = tmpLow + 1
Wend
While (UCASE(pivot) < UCASE(vArray(tmpHi)) And tmpHi > inLow)
tmpHi = tmpHi - 1
Wend
我不知道这种比较的效率如何,但我敢打赌它在长 运行 中可以忽略不计。
您可以在声明时转换 pivot 的大小写,也可以在将数组值添加到数组时转换它们。后者可能是您最好的解决方案,因为转换只发生一次。您可能已经发现 QuickSort 是一种递归算法。还不如删除每次调用必须发生的操作数。
尝试在快速排序 class/module 的顶部添加 Option Compare Text
。 (这应该是代码 all 顶部的第一行(或 Option Explicit
之后的第二行)。)
原因,当然是if因为"A"和"a"的ASCII值不一样,直接在window中做了如下证明:
? Asc("A")
65
? Asc("a")
97
你看到 "A" 出现在 "a" 之前。
现在,在引用的快速排序中,您看到他们正在使用推理比较,使用 >
或 <
类型比较器。这使用了 Ascii 值的严格比较(上图)。 Option Compare Text
将迫使 VBA 考虑 "a" = "A".
试试下面的代码,一次在添加 Option Compare Text
之前,一次在添加之后。
Public Sub test()
Debug.Print "also" < "APPLE"
End Sub
或者,您可以将快速排序修改为不区分大小写。您必须使用 StrComp
函数替换所有隐式比较器(如 <
和 >=
)——确保将 vbTextCompare
作为第三个参数.
例如:
pivot < vArray(tmpHi)
...将替换为:
StrComp(pivot, vArray(tmpHi), vbTextCompare) < 0
使用 StrComp
函数进行一些试验。乍一看似乎很奇怪,但它功能强大,而且(我相信)比普通 VBA 字符串比较更快。