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

raogr8fs  于 2022-11-04  发布在  其他
关注(0)|答案(2)|浏览(269)

我看过很多关于如何按字母顺序对数组中的字符串进行排序的东西。我想知道是否可以取一个单独的字符串(例如,通过TEdit输入的一个单词),并重新排列字符串,使其按字母顺序排序。例如:

  • 你会把单词'strong'
  • 其将被重新排列为'gnorst'
lrpiutwd

lrpiutwd1#

可以在[D]elphi[?]中按字母顺序重新排列字符串吗?
这是一个稍微有点奇怪的问题,因为它的答案是平凡的“是的,当然”。
同样,如果你对 Delphi stringssorting algorithms有一个基本的了解,实现这一点并不困难。所以脾气暴躁的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',并将它显示在消息方块中。
10年或20年前,还没有string.ToCharArrayTArraystring.Create,但当然,你可以手动地(而且很容易地)从字符串中获得一个字符数组,用你在计算机科学101中学到的方法对它进行排序,然后从这个数组中创建一个新的字符串,或者,如果你想聪明一点,你可以在字符串堆对象中就地完成这项工作。
¹实际上,“按字母顺序”排序比您想象的要复杂得多。例如,如何对“aAåäåá4 ΑA êââ"进行排序?瑞典和德国的结果是否相同?另外,请注意和A以及A和Α之间的区别。)

inn6fuwd

inn6fuwd2#

A String can be accessed like an Array already,这样您就可以单独挑选每个字符,并且还可以处理所有字符以进行排序。
Bubble sort不是很高效,但易于编程和理解--之所以这样命名,是因为排序后的元素从下到上(或从左到右)上升,就像水中的气泡会上升一样:

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;

相关问题