我看过很多关于如何按字母顺序排序数组中的字符串的事情。我想知道是否有可能采取一个单独的字符串(例如,只是一个单词,你通过TEdit
输入),并重新安排字符串,使其按字母顺序排列。例如:
- 你可以用
'strong'
这个词, - 将重新排列为
'gnorst'
。
是否可以按字母顺序重新排列[D]elphi[中的字符串?)
这是一个有点奇怪的问题,因为它的答案是平凡的"是的,当然"。
同样,如果你对Delphi字符串和排序算法有基本的了解,实现这一点并不困难。因此,一个脾气暴躁的Stack Overflow用户可能会要求你简单地分别学习这两个主题,然后使用组合的知识来解决任务。
然而,也许真正的问题是,"在现代Delphi版本中是否有规范的(或简单的)方法来做到这一点?">
如果是这样,这个问题就变得更有趣了,而且实际上很容易回答:
var A := 'strong'.ToCharArray;
TArray.Sort<Char>(A);
ShowMessage(string.Create(A));
如果您只包含Generics.Collections
。
第一行声明一个变量A
。它的类型是自动确定的,是TArray<Char>
,即Char
(双字节Unicode字符)的动态数组。A
的值就是字符串的字符数组:'s', 't', 'r', 'o', 'n', 'g'
.
第二行使用默认比较器对数组进行排序。这样A
就变成了'g', 'n', 'o', 'r', 's', 't'
。例如,您可以使用重载方法来指定考虑当前语言环境的不同比较器。¹
第三行从这个字符数组创建一个新的字符串'gnorst'
,并将其显示在消息框中。
十年或二十年前,没有string.ToCharArray
,TArray
或string.Create
。当然,您可以手动(并且很容易地)从字符串中获得字符数组,使用您在计算机科学101中学到的方法对其进行排序,然后从该数组中创建一个新的字符串。或者,如果你想聪明一点,你可以在字符串堆对象中执行此操作。
¹实际上是按字母顺序排序的比你想象的要复杂得多。例如,如何"aAAAaaaA☃4ΑAaaĀ"?瑞典和德国的结果会一样吗?还请注意Ä和Ä之间以及A和Α之间的区别。)
可以像访问Array
一样访问String
,因此您可以自己选择每个字符,并且也可以处理所有字符以进行排序。
冒泡排序不是很有效,但很容易编程和理解-它之所以这样命名是因为排序的元素从下到上(或从左到右)上升,就像水中的气泡会上升一样:
var
sText: String; // Where we will sort its characters (letters)
cTemp: Char; // Spare place for swapping characters
iUnsorted, iSwitch: Integer; // Outer and inner loop
begin
sText:= 'strong';
// The overall sorting must be repeated as per amount of
// characters, minus one.
for iUnsorted:= 1 to Length( sText )- 1 do begin
// Per sorting we compare one character with its following
// character - that's why we need at max one iteration less
// than the amount of characters. And per sorting iteration
// we can ignore more and more of the text's end, because
// all the "big" characters have been sorted there already.
// This equals to one "bubble", carrying the biggest character
// at the left (bottom) to the very right (top).
for iSwitch:= 1 to Length( sText )- iUnsorted do begin
// Is the previous character "bigger" than the next one?
// Exchange both, so the "lower" character always comes
// in front of the "bigger". Note that the [] syntax is
// the same as for accessing array elements, which makes
// the String datatype quite magic/convenient.
if sText[iSwitch]> sText[iSwitch+ 1] then begin
cTemp:= sText[iSwitch]; // Temporarily remember character
sText[iSwitch]:= sText[iSwitch+ 1]; // Overwrite with other
sText[iSwitch+ 1]:= cTemp; // Replace with remembered one
end;
// So you see each step and how the text transforms. Just
// add a TListBox to your form.
Listbox1.Items.Add
( ' iUnsorted='+ IntToStr( iUnsorted )
+ ' iSwitch='+ IntToStr( iSwitch )
+ ' sText='+ sText
);
end;
end;
// Now sText is sorted to 'gnorst'.
end;