如何在Delphi中按字母顺序重新排列字符串?



我看过很多关于如何按字母顺序排序数组中的字符串的事情。我想知道是否有可能采取一个单独的字符串(例如,只是一个单词,你通过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,TArraystring.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;

最新更新