【问题标题】:Shifting a String in C#在 C# 中移动字符串
【发布时间】:2022-01-13 09:38:54
【问题描述】:
  static void Main(string[] args)
  {
     string s = "ABCDEFGH";
     string newS = ShiftString(s);
     Console.WriteLine(newS);
  }
  public static string ShiftString(string t)
  {
     char[] c = t.ToCharArray();
     char save = c[0];
     for (int i = 0; i < c.Length; i++)
     {
        if (c[i] != c[0])
        c[i] = c[i - 1];
     }
     Console.WriteLine(c);
     String s = new string(c);
     return s;
  }

我需要将字符串向左移动一个空格,所以我最终得到了字符串:“BCDEFGHA” 所以我考虑将字符串更改为 char 数组并从那里开始工作,但我不确定如何成功完成这项工作。我很确定我需要一个 for 循环,但我需要一些关于如何将 char 序列向左移动一个空格的帮助。

【问题讨论】:

  • 结果如何?
  • 你说你最终得到了“BCDEFGHA”。这不是你所期望的吗?当给定输入“ABCDEFGH”时,您期望什么结果?
  • 对不起,我可能弄错了。我期待结果“BCDEFGHA”,但这不是我当前的输出。

标签: c# arrays string char shift


【解决方案1】:

这个怎么样?

public static string ShiftString(string t)
{
    return t.Substring(1, t.Length - 1) + t.Substring(0, 1); 
} 

【讨论】:

  • 谢谢,这似乎可行,但我不能 100% 确定这实际上是如何工作的。能解释一下为什么会这样吗?
  • 想象一下你有这个字符串ABC。这部分t.Substring(1, t.Length - 1) 将产生BC 而这部分t.Substring(0, 1) 将返回A
  • 哦等等,我可能知道。将 t.Substring(1, t.Length - 1) 翻译为“BCDEFGH”,将 t.Substring(0, 1) 翻译为“A”,通过连接这些我们得到“BCDEFGHA”?
【解决方案2】:

你可以试试这个:

s = s.Remove(0, 1) + s.Substring(0, 1);

作为扩展方法:

public static class MyExtensions
{
    public static string Shift(this string s, int count)
    {
        return s.Remove(0, count) + s.Substring(0, count);
    }
}

那么你可以使用:

s = s.Shift(1);

【讨论】:

    【解决方案3】:

    解决这种关于移位n个位置问题的算法是复制字符串,连接在一起并得到子字符串。 ( n )

    string s = "ABCDEFGH";
    string ss = s + s; // "ABCDEFGHABCDEFGH"
    

    如果你想移动 n 位置,你可以这样做

    var result = ss.Substring(n, s.length);
    

    【讨论】:

      【解决方案4】:

      我个人会这样做:

      public static string ShiftString(string t){
          string firstLetter = t.Substring(0, 1);
      
          return t.Substring(1) + firstLetter;
      }
      

      【讨论】:

      • 很抱歉不能为此 +1 你,因为该答案已被使用。
      【解决方案5】:

      在 C# 8 及更高版本中...

      向右旋转 一个...

      t = myString[^1] + myString[..^1];
      

      或者,向左旋转 一个...

      t = myString[1..] + myString[0];
      

      或者,向右旋转 一个量...

      t = myString[^amount..] + myString[..^amount];
      

      或者,向左旋转 一个量...

      t = myString[amount..] + myString[..amount];
      

      【讨论】:

        【解决方案6】:

        您可以利用stringIEnumerable&lt;char&gt; 的事实:

        public static string ShiftString(string t){
            return new String(t.Skip(1).Concat(t).Take(t.Length).ToArray());
        }
        

        【讨论】:

          【解决方案7】:

          使用Span<T> 可以显着提高性能。例如:

          public static class StringExtensions
          {
              public static string ShiftString(this string s)
              {
                  return string.Concat(s.AsSpan(1), s.AsSpan(0, 1));
              }
          }
          

          基准测试

          此答案 + 现有答案。使用 span,字符串的移动变得更快并且产生的垃圾更少。

          |  Method |     Data |     Mean |   Median | Allocated |
          |-------- |--------- |---------:|---------:|----------:|
          |    L33t | ABCDEFGH | 18.56 ns | 18.21 ns |      40 B |
          |  Zs2020 | ABCDEFGH | 36.04 ns | 35.20 ns |      96 B |
          | JohnWoo | ABCDEFGH | 47.69 ns | 47.39 ns |     104 B |
          |  AlinaB | ABCDEFGH | 52.56 ns | 52.07 ns |     104 B |
          

          完整的测试代码

          using System;
          using BenchmarkDotNet.Attributes;
          using BenchmarkDotNet.Configs;
          using BenchmarkDotNet.Diagnosers;
          using BenchmarkDotNet.Diagnostics.Windows;
          using BenchmarkDotNet.Running;
          
          namespace ConsoleApp10
          {
              class Program
              {
                  static void Main(string[] args)
                  {
                      var summary = BenchmarkRunner.Run<StringShiftTest>();
                  }
              }
          
              [Config(typeof(Config))]
              public class StringShiftTest
              {
                  private class Config : ManualConfig
                  {
                      public Config() => AddDiagnoser(MemoryDiagnoser.Default, new EtwProfiler());
                  }
          
                  [Params("ABCDEFGH")]
                  public string Data;
          
                  [Benchmark]
                  public string L33t() => string.Concat(Data.AsSpan(1), Data.AsSpan(0, 1));
          
                  [Benchmark]
                  public string Zs2020() => (Data + Data).Substring(1, Data.Length);
          
                  [Benchmark]
                  public string JohnWoo() => Data.Substring(1, Data.Length - 1) + Data.Substring(0, 1);
          
                  [Benchmark]
                  public string AlinaB() => Data.Remove(0, 1) + Data.Substring(0, 1);
              }
          }
          

          【讨论】:

            【解决方案8】:

            StringBuilder 类为您提供更好的性能

            static string ShiftString(string str)
            {
                if (str == null) throw new ArgumentNullException();
                int strLen = str.Length;
                if (strLen == 0) return string.Empty;
                StringBuilder sb = new StringBuilder(strLen);
                sb.Append(str, 1, strLen - 1);
                sb.Append(str[0]);
                return sb.ToString();
            }
            

            【讨论】:

              【解决方案9】:

              以下方法采用数字 n,它表示您想要移动/旋转字符串的次数。如果数字大于字符串的长度,我会按字符串的长度取MOD。

              public static void Rotate(ref string str, int n)
                  {
                      //if the rotation/shift number is less than or =0 throw exception
                      if (n < 1)
                          throw new Exception("Negative number for rotation"); 
                      //if the String is less than 1 character no need to shift
                      if (str.Length < 1) throw new Exception("0 length string");
              
                      if (n > str.Length) // If number is greater than the length of the string then take MOD of the number
                      {
                          n = n % str.Length;
                      }
              
                      StringBuilder s1=new StringBuilder(str.Substring(n,(str.Length - n)));
                      s1.Append(str.Substring(0,n));
                      str=s1.ToString();
              
              
                  }
              

              ///可以利用String操作的Skip和Take函数

               public static void Rotate1(ref string str, int n)
                  {
                      if (n < 1)
                          throw new Exception("Negative number for rotation"); ;
                      if (str.Length < 1) throw new Exception("0 length string");
              
                      if (n > str.Length)
                      {
                          n = n % str.Length;
                      }
              
                      str = String.Concat(str.Skip(n).Concat(str.Take(n)));
              
                  }
              

              【讨论】:

                【解决方案10】:

                您也可以使用简单的 LINQ 语句来实现:

                注意:同样可以通过简单的 for 和/或 while 循环来实现

                string a = "ABCDEFGH";  
                a = new string(Enumerable.Range(0, a.Length).Select(i => (a[(i+1)%a.Length])).ToArray());
                

                【讨论】:

                  【解决方案11】:

                  C# 8.0

                  private static string ShiftString(string t, int shift)
                  {
                      if (shift < 0)//left
                      {
                          shift = -shift;
                          return t[shift..] + t[..shift];
                      }
                      else//right
                      {
                          return t[(t.Length - shift)..] + t[..(t.Length - shift)];
                      }
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2022-11-20
                    • 2013-12-13
                    • 2019-04-26
                    • 1970-01-01
                    • 2021-09-19
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多