【问题标题】:Function for swapping 2 elements in an array doesn't work交换数组中 2 个元素的功能不起作用
【发布时间】:2013-05-11 18:16:51
【问题描述】:

我是 C# 新手,我不明白为什么这段代码不起作用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            char[] sw = "ab".ToCharArray();
            swap(sw[0], sw[1]);
            string end = new string(sw);
            Console.Write(end);
        }

        static void swap(char a, char b)
        {
            char temp = a;
            a = b;
            b = temp;
        }
    }
}

我对控制台的期望是“ba”,但我得到的是“ab”。我能够找到不同的方法来解决这个问题,但我想知道这段代码中的错误是什么。 感谢您的帮助!

【问题讨论】:

    标签: c# swap


    【解决方案1】:

    问题在于swap 方法实际上只是在操作ab 的本地副本。您需要通过引用传递参数。所以你可以像这样定义swap 方法:

        static void swap(ref char a, ref char b)
        {
            char temp = a;
            a = b;
            b = temp;
        }
    

    然后这样称呼它:

        swap(ref sw[0], ref sw[1]);
    

    【讨论】:

    • 这可能是要走的路!
    • @AlexBell 我同意这可能是交换的方式,因为它非常简单。但我通常会尽量避免使用 ref 关键字,因为它往往会导致 IMO 更混乱的 API。
    • 这正是我要做的,但使Swap 通用,因此它适用于任何数组,然后将其放入一些实用程序类中。
    【解决方案2】:

    应该像下面这样修改(注意:在这个例子中,ref char[] arrref 为前缀主要是出于教学目的:默认情况下,数组将由ref 传递)

    namespace ConsoleApplication1
    {
    
            class Program
            {
                static void Main(string[] args)
                {
                    char[] sw = "ab".ToCharArray();
                    swap(0, 1, ref sw );
                    string end = new string(sw);
                    Console.Write(end);
                }
    
                static void swap(int indexA, int indexB, ref char[] arr)
                {
                    char temp = arr[indexA];
                    arr[indexA] = arr[indexB];
                    arr[indexB] =temp;
                }
            }
        }
    

    【讨论】:

      【解决方案3】:

      更通用的数组交换函数:

          public static void Swap<T>(this T[] array, int indexA, int indexB)
          {
              T temp        = array[indexA];
              array[indexA] = array[indexB];
              array[indexB] = temp;
          }
      

      还有一个通用函数来交换几个数组元素:

          public static void Swap<T>(this T[] array, int indexA, int indexB, int length)
          {
              while (length-- > 0)
                  Swap(array, indexA++, indexB++);
          }
      

      【讨论】:

        【解决方案4】:

        您的交换采用两种值类型并在变量之间交换值。那里没有任何东西可以修改原始数组。您需要将您的交换方法修改为:

        static void Swap(char[] array, int a, int b)
        {
            char temp = array[a];
            array[a] = array[b];
            array[b] = temp;
        }
        

        然后您可以从 Main() 中调用它,例如:

        Swap(array, 0, 1);
        

        【讨论】:

          【解决方案5】:

          您正在按值传递参数ab
          有关更多信息,请参阅What's the difference between passing by reference vs. passing by value?

          这里有两种解决方案可以解决您的问题。

          //Pass by value and return the values
          static Tuple<char, char> swap2(char a, char b)
          {
              char temp = a;
              a = b;
              b = temp;
              return new Tuple<char, char>(a, b);
          }
          
          //Pass by reference
          static void swap3(ref char a, ref char b)
          {
              char temp = a;
              a = b;
              b = temp;
          }
          
          public static void Main(string[] args)
          {
              char[] sw2 = "ab".ToCharArray();
              var chars2 = swap2(sw2[0], sw2[1]);
              sw2[0] = chars2.Item1;
              sw2[1] = chars2.Item2;
              //Will print "ba"
              Console.WriteLine(sw2);
          
              char[] sw3 = "ab".ToCharArray();
              swap3(ref sw3[0], ref sw3[1]);
              //Will print "ba"
              Console.WriteLine(sw3);
          }
          

          这里有一个关于你应该使用还是尽量避免使用 ref 关键字的问题。除了最简单的用途外,通常建议尽可能避免使用 ref。 Swap 属于“最简单用途”的范畴,但我建议您在大多数实际情况下尽量避免使用 ref。
          When is using the C# ref keyword ever a good idea?

          【讨论】:

            猜你喜欢
            • 2015-01-02
            • 1970-01-01
            • 1970-01-01
            • 2020-11-06
            • 1970-01-01
            • 1970-01-01
            • 2022-08-03
            • 1970-01-01
            • 2023-03-19
            相关资源
            最近更新 更多