反转一个字符串句子(不一定是每个句子之间的空格)

时间:2022-07-04 21:37:56

I have this string:

我有这个字符串:

com.example.is-this@myname

i would like it to be

我希望它是

myname@this-is.example.com

using .Net, but a straight out concept or an idea would be good to.

使用.Net,但直接的概念或想法会很好。

What i'm currently doing is going over each character, find out if it's one of the "special characters" and assign all prior chars, to a variable of an array, at the end, i'm joining them all together from last to first.

我目前正在做的是遍历每个角色,找出它是否是“特殊字符”之一并将所有先前的字符分配给数组的变量,最后,我将它们从最后一个加入到它们中第一。

is there a possible more efficient way to do this ?

有没有更有效的方法来做到这一点?

4 个解决方案

#1


With little bit of Regex and Linq this is fairly simple.

只需要一点Regex和Linq就可以了。

Idea is that we take words and non word characters as separate token with Regex patten. Then, we just reverse it and join it.

想法是我们将单词和非单词字符作为单独的标记与Regex patten。然后,我们只需将其反转并加入即可。

var tokens =  Regex.Matches("com.example.is-this@myname", @"\w+|\W")
.Cast<Match>()
.Select(x=>x.Value)
.Reverse();

string reversed = string.Concat(tokens);

Output: Ideone - Demo

输出:Ideone - 演示

myname@this-is.example.com

#2


This is the classic word-by-word reversal, with a small twist on delimiters. A solution to this problem is reversing each word individually, and then reversing the whole string. Do not touch delimiters when reversing words.

这是经典的逐字反转,在分隔符上有一点点扭曲。这个问题的解决方案是单独反转每个单词,然后反转整个字符串。在翻转单词时不要触摸分隔符。

First step goes as follows: we find limits of each token, and reverse it in place, like this:

第一步如下:我们找到每个令牌的限制,并将其反转到位,如下所示:

  1. com.example.is-this@myname
  2. moc.example.is-this@myname
  3. moc.elpmaxe.is-this@myname
  4. moc.elpmaxe.si-this@myname
  5. moc.elpmaxe.si-siht@myname
  6. moc.elpmaxe.si-siht@emanym

Reverse the result to get your desired output:

反转结果以获得所需的输出:

moc.elpmaxe.si-siht@emanym -> myname@this-is.example.com

As far as the implementation goes, you can do it by converting the string to an array of characters to make it changeable in place, and write a short helper method that lets you reverse a portion of a char array between indexes i and j. With this helper method in place, all you need to do is to find delimiters and call the helper for each delimited word, and then make one final call to reverse the entire sentence.

就实现而言,您可以通过将字符串转换为字符数组以使其在适当位置更改来执行此操作,并编写一个简短的辅助方法,使您可以在索引i和j之间反转char数组的一部分。使用这个辅助方法,您需要做的就是找到分隔符并为每个分隔的单词调用帮助程序,然后进行最后一次调用以反转整个句子。

#3


You could use the Split C# method.

您可以使用Split C#方法。

The example below is from here.

以下示例来自此处。

using System;

class Program
{
    static void Main()
    {
        string s = "there is a cat";
        // Split string on spaces.
        // ... This will separate all the words.
        string[] words = s.Split(' ');

        foreach (string word in words)
        {
            Console.WriteLine(word);
        }
    }
}

Is as simple as examples get.

就像例子一样简单。

Then you add more conditions to your Split()

然后为Split()添加更多条件

string [] split = strings .Split(new Char [] {'.' , '@', '-' }, 
                                 StringSplitOptions.RemoveEmptyEntries);

The RemoveEmptyEntries just removes unwanted empty entries to your array.

RemoveEmptyEntries只是删除数组中不需要的空条目。

After that you reverse your array using the Array.Reverse method.

之后,使用Array.Reverse方法反转数组。

And then you can stitch your string back together with a Foreach loop.

然后你可以用Foreach循环将你的弦缝合在一起。

As @marjan-venema mentioned in the comments you could populate a parallel array at this point with each delimiter. Reverse it, and then concatenate the string when you are using the Foreach loop at each entry.

正如评论中提到的@ marjan-venema,您可以在此处使用每个分隔符填充并行数组。反转它,然后在每个条目使用Foreach循环时连接字符串。

#4


Here's another way to do it using a List, which has a handy Insert method, as well as a Reverse method.

这是另一种使用List的方法,它有一个方便的Insert方法,以及一个Reverse方法。

The Insert method lets you continue to add characters to the same index in the list (and the others after it are moved to higher indexes).

Insert方法允许您继续将字符添加到列表中的相同索引(以及将其移动到更高索引之后的其他索引)。

So, as you read the original string, you can keep inserting the characters at the start. Once you come to a delimeter, you add it to the end and adjust your insert position to be right after the delimeter.

因此,当您阅读原始字符串时,您可以在开头继续插入字符。进入分界仪后,将其添加到末尾,并将插入位置调整到分隔符后面。

When you're done, you just call Reverse and join the characters back to a string:

完成后,只需调用Reverse并将字符连接回字符串:

public static string ReverseWords(string words, char[] wordDelimeters)
{
    var reversed = new List<char>();
    int insertPosition = 0;

    for(int i = 0; i < words.Length; i++)
    {
        var character = words[i];

        if (wordDelimeters.Contains(character))
        {
            reversed.Add(character);
            insertPosition = i + 1;
            continue;
        }

        reversed.Insert(insertPosition, character);
    }

    reversed.Reverse();
    return string.Join("", reversed);        
}

#1


With little bit of Regex and Linq this is fairly simple.

只需要一点Regex和Linq就可以了。

Idea is that we take words and non word characters as separate token with Regex patten. Then, we just reverse it and join it.

想法是我们将单词和非单词字符作为单独的标记与Regex patten。然后,我们只需将其反转并加入即可。

var tokens =  Regex.Matches("com.example.is-this@myname", @"\w+|\W")
.Cast<Match>()
.Select(x=>x.Value)
.Reverse();

string reversed = string.Concat(tokens);

Output: Ideone - Demo

输出:Ideone - 演示

myname@this-is.example.com

#2


This is the classic word-by-word reversal, with a small twist on delimiters. A solution to this problem is reversing each word individually, and then reversing the whole string. Do not touch delimiters when reversing words.

这是经典的逐字反转,在分隔符上有一点点扭曲。这个问题的解决方案是单独反转每个单词,然后反转整个字符串。在翻转单词时不要触摸分隔符。

First step goes as follows: we find limits of each token, and reverse it in place, like this:

第一步如下:我们找到每个令牌的限制,并将其反转到位,如下所示:

  1. com.example.is-this@myname
  2. moc.example.is-this@myname
  3. moc.elpmaxe.is-this@myname
  4. moc.elpmaxe.si-this@myname
  5. moc.elpmaxe.si-siht@myname
  6. moc.elpmaxe.si-siht@emanym

Reverse the result to get your desired output:

反转结果以获得所需的输出:

moc.elpmaxe.si-siht@emanym -> myname@this-is.example.com

As far as the implementation goes, you can do it by converting the string to an array of characters to make it changeable in place, and write a short helper method that lets you reverse a portion of a char array between indexes i and j. With this helper method in place, all you need to do is to find delimiters and call the helper for each delimited word, and then make one final call to reverse the entire sentence.

就实现而言,您可以通过将字符串转换为字符数组以使其在适当位置更改来执行此操作,并编写一个简短的辅助方法,使您可以在索引i和j之间反转char数组的一部分。使用这个辅助方法,您需要做的就是找到分隔符并为每个分隔的单词调用帮助程序,然后进行最后一次调用以反转整个句子。

#3


You could use the Split C# method.

您可以使用Split C#方法。

The example below is from here.

以下示例来自此处。

using System;

class Program
{
    static void Main()
    {
        string s = "there is a cat";
        // Split string on spaces.
        // ... This will separate all the words.
        string[] words = s.Split(' ');

        foreach (string word in words)
        {
            Console.WriteLine(word);
        }
    }
}

Is as simple as examples get.

就像例子一样简单。

Then you add more conditions to your Split()

然后为Split()添加更多条件

string [] split = strings .Split(new Char [] {'.' , '@', '-' }, 
                                 StringSplitOptions.RemoveEmptyEntries);

The RemoveEmptyEntries just removes unwanted empty entries to your array.

RemoveEmptyEntries只是删除数组中不需要的空条目。

After that you reverse your array using the Array.Reverse method.

之后,使用Array.Reverse方法反转数组。

And then you can stitch your string back together with a Foreach loop.

然后你可以用Foreach循环将你的弦缝合在一起。

As @marjan-venema mentioned in the comments you could populate a parallel array at this point with each delimiter. Reverse it, and then concatenate the string when you are using the Foreach loop at each entry.

正如评论中提到的@ marjan-venema,您可以在此处使用每个分隔符填充并行数组。反转它,然后在每个条目使用Foreach循环时连接字符串。

#4


Here's another way to do it using a List, which has a handy Insert method, as well as a Reverse method.

这是另一种使用List的方法,它有一个方便的Insert方法,以及一个Reverse方法。

The Insert method lets you continue to add characters to the same index in the list (and the others after it are moved to higher indexes).

Insert方法允许您继续将字符添加到列表中的相同索引(以及将其移动到更高索引之后的其他索引)。

So, as you read the original string, you can keep inserting the characters at the start. Once you come to a delimeter, you add it to the end and adjust your insert position to be right after the delimeter.

因此,当您阅读原始字符串时,您可以在开头继续插入字符。进入分界仪后,将其添加到末尾,并将插入位置调整到分隔符后面。

When you're done, you just call Reverse and join the characters back to a string:

完成后,只需调用Reverse并将字符连接回字符串:

public static string ReverseWords(string words, char[] wordDelimeters)
{
    var reversed = new List<char>();
    int insertPosition = 0;

    for(int i = 0; i < words.Length; i++)
    {
        var character = words[i];

        if (wordDelimeters.Contains(character))
        {
            reversed.Add(character);
            insertPosition = i + 1;
            continue;
        }

        reversed.Insert(insertPosition, character);
    }

    reversed.Reverse();
    return string.Join("", reversed);        
}