提问人:tmsh 提问时间:5/17/2019 最后编辑:Jon Skeettmsh 更新时间:5/17/2019 访问量:363
如何在 C 中通过引用传递#
How to pass by reference in C#
问:
我正在编写一个快速排序类,模仿 Sedgewick 的“算法 4”中给出的代码。原始代码是用 Java 编写的。我用 C# 翻译了核心部分,但它似乎不起作用。似乎问题出在了线上,但我不知道如何纠正它。a = a.OrderBy(x => r.Next()).ToArray()
我试图添加 s 和方法签名,但是一旦我调用了 中的函数,编译器就抱怨 .
我还尝试使第一个返回一个 ,即排序数组。但是,当我像这样调用它时,它会抛出一个运行时错误说ref
Sort
Partition
Sort(ref a)
Main
cannot converte ref System.String[] to ref System.IComparable[]
Sort
IComparable[]
Main
string[] nums = (string[]) Sort(nums)
Unable to cast object of type 'System.IComparable[]' to type 'System.String[]'.
public class Quick
{
public static void Sort(IComparable[] a)
{
Random r = new Random();
a = a.OrderBy(x => r.Next()).ToArray();
Sort(a, 0, a.Length - 1);
}
private static void Sort(IComparable[] a, int lo, int hi)
{
if (lo >= hi) return;
int p = Partition(a, lo, hi);
Sort(a, lo, p - 1);
Sort(a, p + 1, hi);
}
private static int Partition(IComparable[] a, int lo, int hi)
{
int i = lo, j = hi;
IComparable p = a[lo];
while (true)
{
while (Less(a[++i], p))
{
if (i == hi)
break;
}
while (Less(p, a[--j]))
{
if (j == lo)
break;
}
if (i >= j) break;
Exch(a, i, j);
}
Exch(a, lo, j);
return j;
}
private static void Exch(IComparable[] a, int lo, int hi)
{
IComparable tmp = a[lo];
a[lo] = a[hi];
a[hi] = tmp;
}
private static bool Less(IComparable a, IComparable b)
{
return a.CompareTo(b) < 0;
}
public static void Main(string[] args)
{
string[] nums = File.ReadAllLines(args[0]);
for (int i = 0; i < nums.Length; i++)
{
Console.WriteLine(nums[i]);
}
Sort(nums);
Console.WriteLine("After sorting:");
for (int i = 0; i < nums.Length; i++)
{
Console.WriteLine(nums[i]);
}
Console.ReadKey();
}
}
第二个 WriteLine 应该打印出排序后的数组,但它没有。
答:
您需要返回排序后的数组,因为就像您说的那样,它是按值传递的,而不是按引用传递的。 将返回类型而不是 void 添加到 Sort 方法并返回 a;
和改变
排序(nums);
自
nums=排序(nums);
这里的问题不是通过引用传递,而是这一行,正如您所确定的:
a = a.OrderBy(x => r.Next()).ToArray();
您正在提供一个新值,这与仅修改 的内容不同。由于该方法对数组进行就地排序,因此不应创建新数组,并且不必在对数组进行排序之前对其进行洗牌。a
a
Sort
因此,删除这两行应该可以使您的代码正常工作:
Random r = new Random();
a = a.OrderBy(x => r.Next()).ToArray();
当您尝试从 返回数组时,您似乎遇到了一些问题。您可以通过将所有方法设置为泛型来解决此问题,并将泛型参数限制为:Sort
T
IComparable<T>
public static T[] Sort<T>(T[] a) where T: IComparable<T>
{
Random r = new Random();
a = a.OrderBy(x => r.Next()).ToArray();
Sort(a, 0, a.Length - 1);
return a;
}
private static void Sort<T>(T[] a, int lo, int hi) where T: IComparable<T>
{
if (lo >= hi) return;
int p = Partition(a, lo, hi);
Sort(a, lo, p - 1);
Sort(a, p + 1, hi);
}
private static int Partition<T>(T[] a, int lo, int hi) where T: IComparable<T>
{
int i = lo, j = hi;
T p = a[lo];
while (true)
{
while (Less(a[++i], p))
{
if (i == hi)
break;
}
while (Less(p, a[--j]))
{
if (j == lo)
break;
}
if (i >= j) break;
Exch(a, i, j);
}
Exch(a, lo, j);
return j;
}
private static void Exch<T>(T[] a, int lo, int hi)
{
T tmp = a[lo];
a[lo] = a[hi];
a[hi] = tmp;
}
private static bool Less<T>(T a, T b) where T: IComparable<T>
{
return a.CompareTo(b) < 0;
}
评论
as IComparable<string>
ref
Sort()
Main
Sort()
Main
Main
Sort()
Sort()