在不使用 C# 中的 split 和 substring 等内置函数的情况下反转字符串中的单词

Reverse the words in a string without using builtin functions like split and substring in C#

我写了以下内容:

    class Program
    {
    public static void Main(string[] args)
    {

        string name = "Hello World"

        StringBuilder builder = new StringBuilder();
        for (int i = name.Length - 1; i >= 0; i--)
        {
            builder.Append(name[i]);
        }
        string newName =builder.ToString();

        Console.WriteLine(newName);

    }
}

我得到 "dlrow olleh " 作为输出。我想要"World Hello "。

在伪代码中,此问题的解决方案可能如下所示:

result = empty string
last = input.length
for i from input.length - 1 to 0
    if input(i) is whitespace or i is 0
        for j from i to last - 1
           append input[j] to result
        last = i

这从字符串的后面开始,向后循环。当它找到一个空格(或到达 stirng 的开头)时,它知道它找到了一个完整的单词并将其添加到列表中。变量 last 跟踪添加的最后一个单词的起始位置。

您需要稍微调整一下才能使单词之间的空格正确。

我写了一个使用 2 个循环的快速解决方案。 第一个循环从左到右遍历字符串。 当它遇到空格(分隔单词)时,第二个循环开始。

第二个循环是从右到左遍历单词。第二个循环不能从左到右,因为我们不知道单词将从哪里开始(除非我们记得我们在哪里遇到了前面的空格)。因此,第二个循环从右到左遍历字符串,直到它遇到一个空格(单词的开头),或者直到索引变为 0(这是一个极端情况)。在第一个循环中可以观察到相同的极端情况。

这里是:

String name = "Hello World";
StringBuilder builder = new StringBuilder();

for (int i = 0; i < name.length(); i++)
{
    char tmp = name.charAt(i);
    if(tmp == ' ' || i == name.length() - 1) {
        // Found a whitespace, what is preceding must be a word
        builder.insert(0,  ' ');
        for(int j = i - 1; j >= 0; j--) {
            if(i == name.length() - 1 && j == i - 1) {
                // Exceptional case (necessary because after the last word there is no whitespace)
                builder.insert(0, name.charAt(i));
            } 

            char curr = name.charAt(j);

            if(curr == ' ') {
                // We passed the beginning of the word
                break;
            }
            else if(j == 0) {
                builder.insert(0,  curr);
                break;
            }

            //builder.append(curr);
            builder.insert(0, curr);
        }
    }
}

String newName = builder.toString();
System.out.println(newName);

请注意,这是 java 代码,但将其转换为 C# 应该很简单。

不能使用 "built-in" 函数并不意味着不能编写自己的函数。您应该从这样的任务中学到的是如何将问题分解为一组子问题。

string Reverse(string pInput) {
   // iterate backwards over the input, assemble a new string, and return it
}

List<string> Split(string pInput, char pSplitOn) {
   // iterate forwards over the input
   // build up a new string until the split char is found
   // when it is found, add the current string to a list
   // and start the building string over at empty
   // maybe only add strings to the list if they aren't empty
   // (although that wouldn't preserve extra whitespace, which you may want)
   // make sure to add the end of the string since it probably
   // doesn't end with the split char
   // return the list
}

string Join(List<string> pWords, char pSeparator) {
   // build up a new string consisting of each of the words separated by the separator
}

string ReverseWords(string pInput) {
   // split the input on a space
   // for each "word" in the resulting list, reverse it
   // join the reversed words back together into one string, with spaces separating them
}

这假定您将遇到的唯一空白由空格组成。还假设您被允许使用 List<T>.