2013-11-26 21 views
0

因此,我需要采用人名和年龄,将它们存储在两个单独的数组中,按年龄对它们进行排序,然后显示结果在一个列表框中。我把所有的东西放回到列表框中。这听起来很简单,但foreach循环(从我对C#的基本理解)只能取其中一个数组的值。我需要同一行上的名称和年龄,因为它们连接在一起,所以我决定切换到for循环。然而,尽管我在年龄上的排序工作得很好,但我无法让这个名字与年龄匹配。这里是我的一些代码:C#:将字符串[]和int []元素连接在一起以便在排序时保持在一起int []

const int MAX = 100; 
    int count = 0; 

    int[] Age = new int[MAX]; 
    string[] NameEntry = new string[MAX]; 

只是为了告诉你我是如何声明数组的。这是我的“商店” click事件:

int age; 

     if (txtName.Text == "") 
     { 
      lblWarningMessage.Text = "There is an error with your entries. A name must be entered!"; 
      btnClearWarn.Show(); 
     } 
     else 
     { 
      NameEntry[count] = txtName.Text; 

      if (int.TryParse(txtAge.Text, out age)) 
      { 
       Age[count] = age; 

       txtAge.Clear(); 
       txtName.Clear(); 
       txtName.Focus(); 

       lstbxResults.Items.Add(NameEntry[count] + " is " + Age[count].ToString() + " years old."); 

       count++; 
      } 
      else 
      { 
       lblWarningMessage.Text = "There is an error with your entries. The Age entry must be an integer."; 
       btnClearWarn.Show(); 
      } 
     } 

最后,排序操作以及随后的for循环将其添加到我的列表框:

 Array.Resize(ref NameEntry, count); 
     Array.Resize(ref Age, count); 

     lstbxResults.Items.Clear(); 
     int minAge = 0; 
     int minIndex = 0; 

     for (int a = 0; a < Age.Length - 1; a++) 
     { 
      minAge = Age[a]; 
      minIndex = a; 

      for (int b = a + 1; b < Age.Length; b++) 
      { 
       if (Age[b] < minAge) 
       { 
        minAge = Age[b]; 
        minIndex = b; 
       } 
      } 

      OrderByAges(ref Age[minIndex], ref Age[a]); 
     } 

     for (int c = 0; c < Age.Length; c++) 
     { 
      lstbxResults.Items.Add(NameEntry[c] + " is " + Age[c] + " years old."); 
     } 
    } 

    private void OrderByAges(ref int p1, ref int p2) 
    { 
     int temp = p2; 
     p2 = p1; 
     p1 = temp; 
    } 

是的,我知道的Array.sort会更快,但这是为了达到同样的目的,这就是我被教导如何做到的。关于如何将“NameEntry”中的元素链接到“Age”的任何想法,并在排序时与Age一起更改?

+1

无论何时您更改数组1中的项目的索引,请更改数组2中的相同索引。所以如果Age [2]更改为Age [5],请将Name [2]更改为Name [5]。但它会使LOT更加注重创建包含Age和Name的单个对象。 –

+1

也许您应该创建一个类来将这两个('age'和'name')一起存储,并对类实例的数组进行排序? – MarcinJuraszek

回答

3

你真的应该在这种情况下使用“Array.Sort”。它能够共同分拣两个相连的数组键和值,如:

Array.Sort(Age, NameEntry, 0, count); 

如果老师真的坚持不使用的Array.Sort一个解决方案,只需使用一个快速排序的实现,仅仅是交换

这样的(未测试):在同一时间两个键和值的元素

public static class CoSorter 
{ 
    public static void Sort<TKey, TValue>(this TKey[] keys, TValue[] values, int start, int count) 
    { 
     QuickCosort(keys, values, start, count - 1, Comparer<TKey>.Default); 
    } 

    public static void Sort<TKey, TValue>(this TKey[] keys, TValue[] values, int start, int count, IComparer<TKey> comparer) 
    { 
     QuickCosort(keys, values, start, count - 1, comparer); 
    } 

    private static void QuickCosort<TKey, TValue>(TKey[] keys, TValue[] values, int left, int right, IComparer<TKey> comparer) 
    { 
     int i = left, j = right; 
     var pivot = keys[(left + right)/2]; 

     while (i <= j) 
     { 
      while (comparer.Compare(keys[i], pivot) < 0) 
      { 
       i++; 
      } 

      while (comparer.Compare(keys[j], pivot) > 0) 
      { 
       j--; 
      } 

      if (i <= j) 
      { 
       // Swap 
       var tmpKey = keys[i]; 
       var tmpVal = values[i]; 
       keys[i] = keys[j]; 
       values[i] = values[j]; 
       keys[j] = tmpKey; 
       values[j] = tmpVal; 

       i++; 
       j--; 
      } 
     } 

     // Recursive calls 
     if (left < j) 
     { 
      QuickCosort(keys, values, left, j, comparer); 
     } 

     if (i < right) 
     { 
      QuickCosort(keys, values, i, right, comparer); 
     } 
    } 
} 

或者你可能要考虑这个有点难,看看,也许你需要一个数据结构,而不是属于两个值的数组。

+0

@HonzaBrestan thx是我忘记了开始索引。纠正。 – Alex

+0

这就像一个魅力,但我特别指示不要使用Array.Sort。否则有什么办法可以做到这一点,还是我的老师让我走上了一条无处可去的道路? – user3034550

+0

@ user3034550哈哈,你没有提到这是你的功课。好吧,让我们来帮助你。我会为我的答案添加一个合并排序例程。 – Alex

2

对亚历克斯答案中OP的评论的反应 - 如果这是一项家庭作业/学校作业,首先在StackOverflow上很好地定义这个问题。

如果你的老师不希望你使用Array.Sort,是否有任何机会主要是关于执行排序算法?如果是这样,显然你应该实现自己的,而不是使用库函数 - 并且最好在问题中使用它。

反正不管它是不是最明智的解决方案是创建一个包含NameAge一个Person类,排序数组的人按年龄,填上自己的姓名列表框的情况下或(或者更确切地说,使用数据绑定, like this)。在面向对象的世界中,两个相关值的单独阵列没有多大意义,并且难以维护 - 正如您的情况所见。

0

如果您必须使用两个单独的并行数组,则每个数组的元素都由索引链接。但是它们只是因为你碰巧把这些元素放在同一个索引中而已。这不是自动的。所以,当你在一个数组中移动某些东西时,记住使用的索引,并使用它们在另一个数组中移动相同的东西。

您的代码在双重嵌套循环中移动了年龄,因此也要在该代码中移动该名称。