Sorry for the vague title but I'll try and describe what my problem as best as I can below.
Basically I have 5 string arrays that all hold data relevant to the same index in the other arrays. For example, element 5 in array 1 corresponds to element 5 in arrays 2, 3, 4 and 5.
What I have done is used the Quicksort algorthim to sort array 1 into alphabetical order. The problem is that when the array is sorted, no longer do elements in the other arrays correspond since the other arrays haven't been sorted.
What I need is some way to swap the same elements around in the other 4 arrays as has been down to array 1. For example, if element 2 in array 1 is swapped to element 55, then element 2 in the other 4 arrays need to be swapped to element 55 in their array and vice versa.
The end goal is to display all the data in a specific element across all 5 arrays.
Below I have added the quicksort algorithm I'm using and added 3 example arrays that need sorting:
string[] array1 = {"z","y","x","a"};
string[] array2 = {"26","25","24","1"};
string[] array3 = { "black","yellow","white","red" };
// The first 2 arrays should clarify my point further.
// I use Quicksort to sort array 1
public static void QuicksortSTRING(IComparable[] elements, int left, int right)
{
int i = left, j = right;
IComparable pivot = elements[(left + right) / 2];
while (i <= j)
{
while (elements[i].CompareTo(pivot) < 0)
{
i++;
}
while (elements[j].CompareTo(pivot) > 0)
{
j--;
}
if (i <= j)
{
// Swap
IComparable tmp = elements[i];
elements[i] = elements[j];
elements[j] = tmp;
i++;
j--;
}
}
// Recursive calls
if (left < j)
{
QuicksortSTRING(elements, left, j);
}
if (i < right)
{
QuicksortSTRING(elements, i, right);
}
}
If you need any other info just ask.
答案 0 :(得分:2)
最好将三个相关的字符串放在一个对象中:
sealed class RelatedInformation // or struct, you decide
{
public string First;
public string Second;
public string Third;
}
然后对这些对象的列表进行排序:
var myList = new List<RelatedInformation>();
// insert code that populates the list here
myList.Sort((a, b) => a.First.CompareTo(b.First));
或者,如果它需要是一个数组:
var myArray = /* obtain the RelatedInformation[] here */;
Array.Sort(myList, (a, b) => a.First.CompareTo(b.First));
此外,您不需要自己实施Quicksort(除非这是家庭作业?:))。您只需将Array.Sort或List<T>.Sort与lambda表达式一起使用即可指定排序标准。
如果您使用上述代码,则甚至不需要实现IComparable<T>
接口。但是,如果RelatedInformation
类(或结构)用于许多与其排序有关的地方,那么无论如何都要明智地实施它;然后你可以抛弃lambdas:
sealed class RelatedInformation : IComparable<RelatedInformation>
{
public string First;
public string Second;
public string Third;
public int CompareTo(RelatedInformation other)
{
return First.CompareTo(other.First);
}
}
// ...
var myList = new List<RelatedInformation>();
// insert code that populates the list
myList.Sort();
但是,由于您明确询问三阵列情况,这里是一个可以在该约束下工作的解决方案。而不是排序任何一个数组,我们的想法是排序索引列表。我将使用LINQ,因为它非常简洁易读:
var sortedIndexes = Enumerable.Range(0, array1.Length)
.OrderBy(i => array1[i])
.ToArray();
var sortedArray1 = sortedIndexes.Select(i => array1[i]).ToArray();
var sortedArray2 = sortedIndexes.Select(i => array2[i]).ToArray();
var sortedArray3 = sortedIndexes.Select(i => array3[i]).ToArray();
很短,嗯?当然,在调用OrderBy
时,您可以指定要排序的任何其他数组。
请注意,如果任何数组的更短,此代码将抛出异常,并且如果任何数组更长,它将静默地丢弃项目< / em>比第一个。对象列表解决方案的一个主要好处是您无需担心这一点。
作为补充信息,LINQ的OrderBy
是稳定排序;这意味着array1
具有相同字符串的项目保持相同的顺序。 Array.Sort
和List<T>.Sort
没有稳定的排序。
您甚至可以使用此方法按多个条件进行排序;例如,假设您要按array1
中的字符串排序,但只要array1
对某些项具有相同的字符串,您就希望这些项按array2
中的任何内容排序。您可以使用ThenBy
:
var sortedIndexes = Enumerable.Range(0, array1.Length)
.OrderBy(i => array1[i])
.ThenBy(i => array2[i])
.ToArray();
答案 1 :(得分:1)
您已经对这三项信息进行了排序。尝试创建一个类来保存它们。如果你愿意,它可以是你的一个程序类中的内部类。
struct MyThing :IComparable {
char a;
int b;
string c;
}
然后制作List<MyThing>
。然后用您的数据填充它。
您需要为您的班级实施IComparable interface (requiring your own CompareTo method),因此它知道对a
或您想要排序的任何内容进行排序。
然后使用内置的List.Sort()
函数或您自己的快速排序方法。
答案 2 :(得分:0)
我认为如果将所有相关信息存储在一个数组中会更有意义,例如:
var array = new[] { Tuple.Create("z", "26", "black"),
Tuple.Create("y", "25", "yellow"),
Tuple.Create("x", "24", "white"),
Tuple.Create("a", "1", "red") };
然后,您可以使用您喜欢的任何键对数组进行排序,并在相应的位置保留其他元素。
答案 3 :(得分:0)
您可以通过将所有相关字符串放入单个类来实现此目的,而不是将它们全部保存在单独的数组中。
例如:
public class Demo
{
public string Key;
public string S1;
public string S2;
public override string ToString()
{
return string.Format("Key: {0}, S1: {1}, S2: {2}", Key, S1, S2);
}
}
然后,当您想要对其进行排序时,您需要一种方法来确定比较元素时要使用的属性。做这件事有很多种方法;一个是制作类型工具IComparable<T>
。
然而,还有另一种更灵活的方法。您可以为sort方法提供可用于比较元素的IComparer<T>
对象。
使用此功能,您可以选择&#34;比较时要使用的类的成员。
以下是一个完整的例子:
using System;
using System.Collections.Generic;
namespace Demo
{
public class Demo
{
public string Key;
public string S1;
public string S2;
public override string ToString()
{
return string.Format("Key: {0}, S1: {1}, S2: {2}", Key, S1, S2);
}
}
static class Program
{
static void Main()
{
var list = new List<Demo>
{
new Demo {Key = "Z", S1 = "Z1", S2 = "Z2"},
new Demo {Key = "Y", S1 = "Y1", S2 = "Y2"},
new Demo {Key = "X", S1 = "X1", S2 = "X2"},
new Demo {Key = "W", S1 = "W1", S2 = "W2"},
new Demo {Key = "V", S1 = "V1", S2 = "V2"}
};
// Rather than write your own IComparer<Demo> implementation, you can
// leverage a built-in .Net implementation by using
// Comparer<Demo>.Create() as follows:
var keyComparer = Comparer<Demo>.Create((x, y) => string.Compare(x.Key, y.Key, StringComparison.Ordinal));
QuicksortSTRING(list, 0, list.Count-1, keyComparer);
Console.WriteLine(string.Join("\n", list));
}
public static void QuicksortSTRING<T>(IList<T> elements, int left, int right, IComparer<T> comparer)
{
int i = left, j = right;
var pivot = elements[(left + right)/2];
while (i <= j)
{
while (comparer.Compare(elements[i], pivot) < 0)
{
i++;
}
while (comparer.Compare(elements[j], pivot) > 0)
{
j--;
}
if (i <= j)
{
// Swap
T tmp = elements[i];
elements[i] = elements[j];
elements[j] = tmp;
i++;
j--;
}
}
// Recursive calls
if (left < j)
{
QuicksortSTRING(elements, left, j, comparer);
}
if (i < right)
{
QuicksortSTRING(elements, i, right, comparer);
}
}
}
}