【问题标题】:Function which takes a string as input and returns an array of strings as follows ABC(abcde) should return [Abcde, aBcde, abCde, abcDe, abcdE]将字符串作为输入并返回字符串数组的函数如下 ABC(abcde) 应返回 [Abcde, aBcde, abCde, abcDe, abcdE]
【发布时间】:2018-07-29 18:35:58
【问题描述】:

我是这样做的,但是它删除了字符串前面的字符,它的输出是 (Magic,Agic,Gic,Ic,C) 但我希望整个字符串在之前和之后连接起来。

      public string[] Transform(string st)
 {
     string[] arr = new string[st.Length];

     string[] arr1 = new string[st.Length];
     for (int x = 0; x < st.Length; x++)
     {
         arr1[x] = char.ToLower(st[x]) + "".ToString();
     }
     for (int i = 0; i < st.Length; i++)
     {
         string st1 = "";
         {
             st1 = char.ToUpper(st[i]) + st.Substring(i + 1);
         }
         arr[i] = st1; 
     }
         return arr; 

 }

【问题讨论】:

  • 您将 arr1 创建为一个数组,然后再也不会引用它。这是一个线索。调试器将帮助定位其他问题。
  • arr1 添加错误 我忘记从代码中删除它 我为此目的测试了其他一些 scnerio 我创建了 arr1

标签: c# asp.net .net arrays function


【解决方案1】:

你可以用一个循环来做到这一点:

public static string[] Transform(string str)
{
    var strs = new List<string>();
    var sb = new StringBuilder();

    for (int i = 0; i < str.Length; i++)
    {
        sb.Clear();
        sb.Append(str);
        sb[i] = char.ToUpper(str[i]);
        strs.Add(sb.ToString());
    }
    return strs.ToArray();
}

这样做是将str 添加到StringBuilder,然后使用该字符的大写版本修改索引字符。例如,输入 abcde 将给出:

Abcde abcde abCde ABCDE abcdE

Try it out on DotNetFiddle

如果你想变得非常花哨,我敢肯定有一些复杂的 LINQ 可以做到这一点,但这为你提供了一个基本框架来了解它如何工作。

【讨论】:

  • 如果您知道确切的结果长度并计划返回一个数组,则首先构造和填充List&lt;string&gt; 是不必要且效率低下的。
  • 谢谢 Ron Beyer,它真的很有帮助,它解决了我的问题。
  • @RuudKobes 唯一的事情是在构造列表时设置列表的长度,但是在这种情况下,List 与数组相比并不是真的低效,它使用数组作为无论如何,一个后备商店。您可以在其中放置一个数组,但我们并不是在谈论内存节省或处理方面的太多问题。
【解决方案2】:

您忘记添加字符串的左侧部分。尝试这样做:

st1 = st.ToLower().Substring + char.ToUpper(st[i]) + st.Substring(i + 1);

【讨论】:

  • 对不起。我忘记了“0”。这是正确答案: If (i=0) st1 = char.ToUpper(st[i]) + st.Substring(i + 1);否则 st1 = st.ToLower().Substring(i-1) + char.ToUpper(st[i]) + st.Substring(i + 1);
  • 您应该编辑您的答案以包含更新的代码,而不是将其发布在评论中。
  • @RonBeyer 谢谢你,下次会使用你的推荐!它只是“第一滴血”:)
【解决方案3】:

这里。这比使用字符串生成器和列表的方法快一倍

public static string[] Transform(string str)
{
    var strs = new string [str.Length];
    var sb = str.ToCharArray();

    char oldCh;
    for (int i = 0; i < str.Length; i++)
    {
        oldCh = sb[i];
        sb[i] = char.ToUpper(sb[i]);
        strs[i] = new string (sb);
        sb[i] = oldCh;
    }
    return strs;
}

无需将字符串清除并继续读取字符串生成器。我们还知道数组的大小,以便可以在开始时分配。

【讨论】:

    【解决方案4】:
    1. 我为您的问题写了一个答案(这是第二个代码 sn-p),您可以根据需要对其进行修改,例如将返回类型更改为 string[],或者如果您想坚持使用 ToArray() 扩展方法.我认为这种方式更具可读性。

    与@Ron Beyer 的回答相比,我决定放一个小分析器来检查 CPU 使用率和内存。

    这是我的第一次尝试:

        public static void Main()
        {
            var result = Transform("abcde");
            result.ToList().ForEach(WriteLine);
        }
    
        public static IEnumerable<string> Transform(string str)
        {
            foreach (var w in str)
            {
                var split = str.Split(w);
    
                yield return  split[0] + char.ToUpper(w) + split[1];
            }
        }
    

    结果:

        Abcde
        aBcde
        abCde
        abcDe
        abcdE
    

    代码小提琴https://dotnetfiddle.net/gnsAGX

    上面的代码有一个很大的缺点,它只有在传递的单词有唯一字母时才有效。因此“aaaaa”不会产生正确的结果。

    1. 这是我的第二次成功尝试,似乎适用于任何字符串输入。我使用了 StringBuilder 的一个实例来减少需要在一个实例上创建和管理的对象数量,而不是复制这么多对象,因此它更加优化。

      public static void Main()
      {
          var result = Transform("aaaaa");
          result.ToList().ForEach(WriteLine);
      }
      
      public static IEnumerable<string> Transform(string str)
      {
          var result = new StringBuilder(str.ToLower()); 
          for( int i = 0; i < str.Length; i++)
          { 
              result[i] = char.ToUpper(str[i]);
              yield return result.ToString();
              result[i] = char.ToLower(str[i]);
          }
      }
      

      结果:

      Aaaaa
      aAaaa
      aaAaa
      aaaAa
      aaaaA
      

      代码小提琴:https://dotnetfiddle.net/tzhXtP

    2. 测量执行时间和内存使用情况。

      我将使用 dotnetfiddle.net 状态面板,使其更容易。 Fiddle 几乎没有限制,例如 10 秒的代码执行时间和使用的内存
      此外差异非常显着。 我测试了 14 000 次重复的程序,我的代码另外将输出更改为 array[]。

    它略微减少了执行时间。 希望这会有所帮助!

    【讨论】:

    • 您的基准具有误导性并且根本不正确,因为您的替代方案只是通过定义 IEnumerable 来声明结果的规范。您需要实际枚举结果以获得可比较的结果。如果您还将字符串长度减少到合理的大小,则只会有很小的改进。 IEnumerable 是否真的有帮助取决于使用情况,但 OP 专门要求一个数组。
    • @RuudKobes IEnumerable 确实如此,谢谢,我修复了它。我可以同意小的改进。最后,14000 次重复需要 2.39 秒。更快,但令我惊讶的是记忆保持不变。我的目标是创建最少数量的对象和最容易理解的代码。由 Jim Berg 编写的更有效的方法与我的类似,但对最简单的类型进行操作。请记住,越少并不总是越快,但有时它并不是最重要的。
    • 确实如此。但是,您的基准测试结果仍然受到您使用的非常长的字符串的影响。如果您使用“qwerty...”字符串的单次迭代,您的解决方案实际上会比您要比较的解决方案慢
    【解决方案5】:
    public static string[] Transform(string str)
    {
        var strs = new string [str.Length];
        var sb = str.ToCharArray();
    
        char oldCh;
        for (int i = 0; i < str.Length; i++)
        {
            oldCh = sb[i];
            sb[i] = char.ToUpper(sb[i]);
            strs[i] = new string (sb);
            sb[i] = oldCh;
        }
        return strs;
    }
    

    【讨论】:

    • Jim berg 的回答是对我帖子的正确有效回答
    • 要表明这一点,您可以通过单击答案左侧的绿色复选标记来接受该答案。
    猜你喜欢
    • 2017-09-08
    • 2015-11-20
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 2015-09-20
    • 1970-01-01
    相关资源
    最近更新 更多