删除和查找数组中的元素

时间:2018-06-11 20:27:32

标签: c# arrays

我想知道如何修复我的代码中的小问题... 当输出删除我想要的元素时,输出会复制数组中的最后一个元素。 有什么建议?

以下是代码:

static void Main(string[] args)
{
    int[] List = { 12, 122, 2, 3, 4, 5, 6 };
    int nrElements =7;
    for (int i = 0; i <= nrElements -1; i++)
    {
        Console.Write(" " + List[i] );
    }
    Console.WriteLine("Above is the array");
    Console.WriteLine("What number element do you want to delete?");
    int wanted = int.Parse(Console.ReadLine());

    FindElement(List, nrElements, wanted);
    DeleteElement(List, nrElements, wanted);

    for (int i = 0; i <= nrElements -1; i++)
    {
        Console.Write(List[i] +" ");
    }
    Console.ReadLine();
}

private static void DeleteElement(int[] list, int nrelement , int wanted)
{
    for (int i = wanted; i <= nrelement - 2; i++)
    {
        list[i] = list[i + 1];
    }
    nrelement--;
}

public static int FindElement(int[] list, int nrElements, int wanted)
{
    for (int i = 0; i <= nrElements-1 ; i++)
    {
        if (list[i] == wanted)
        { return i; }
        else if (list[i] != wanted)
        { return -1; }               

    }
    return 0;
}

2 个答案:

答案 0 :(得分:1)

private static void DeleteElement(int[] list, int nrelement , int wanted)
{
    for (int i = wanted; i <= nrelement - 2; i++)
    {
        list[i] = list[i + 1];
    }
    nrelement--;
}

在上面的代码中,nrelement是一个int,因此是一个结构,其值传递给方法。在方法中更改它的值不会影响方法之外的任何内容。

立即解决方案是将nrelement作为ref参数传递,或者您可以返回nrelement的值,并让调用者使用该值。但是,重新考虑处理数组的整体设计(例如使用List<>)可能最终会成为更好的解决方案。

答案 1 :(得分:1)

你的代码存在很多问题。

首先,FindElement()方法并不能完全按照您的想法执行。

public static int FindElement(int[] list, int nrElements, int wanted)
{
    for (int i = 0; i <= nrElements - 1; i++)
    {
        if (list[i] == wanted)
        {
            return i;
        }
        else if (list[i] != wanted)
        {
            return -1;
        }
    }
    return 0;
}

如果您将方法翻译为英语,那就是它的作用:

  • 从头开始迭代列表。
  • 查看第一个元素是否是您正在寻找的内容。
  • 如果是,则返回该索引(并退出方法)。
  • 如果不是,则返回-1和(并退出方法)。

因此,除非您要查找的元素位于列表的第一个索引中,否则您将找不到它,并在循环一次迭代后退出该方法。

你可以使用LINQ的一行代码解决这个问题,但我觉得这不是目标。我会做一些不同的事情。

  • 从头开始迭代列表。
  • 查看第一个元素是否是您正在寻找的内容。
  • 如果是,则返回该索引(并退出方法)。
  • 如果没有,继续循环到下一次迭代,看看第二个元素是否是您正在寻找的。
  • 重复上述操作直至列表末尾。

所以你的代码看起来应该是这样的。是的,我将摆脱nrElements,你不需要将它作为一个单独的参数传递。另外,请记住将此方法的结果保存在main()中,以便在下一个方法中使用。

public static int FindElement(int[] list, int wanted)
{
    for (int i = 0; i < list.Length; i++)
    {
        // If item is found in the ith position, retun i;
    }
    // If you reach here, that means the item you're looking for is not in the list. So return -1.
}

接下来,让我们转到您的DeleteElement()方法。

您对nrElement的使用不正确,没有多大意义。 for循环如何工作的基本思想是这样的;从某个初始值开始,并继续增加(或减少)计数器,直到满足特定条件(值)。所以你应该通常增加/减少的是所述计数器,而不是它应该满足的条件。但是在每一步你都在改变这种状况。在极少数情况下这可能是合理的,但现在通常是如何使用它。

接下来,您的“删除”方式也存在问题。你真正在做的是从要删除的元素的索引开始向前移动元素。所以基本上当你完成后,你的最后两个元素将是相同的,你的前一个元素。

因此,在执行上述步骤后,您需要执行Array.Resize()

// Notice the ref.
private static void DeleteElement(ref int[] list, int index)
{
    for (int i = index; i < list.Length - 1; i++)
    {
        list[i] = list[i + 1];
    }
    // This step removes the last element from the array.
    Array.Resize(ref list, list.Length - 1);
}

现在,您需要更改main()

  • 摆脱nrElement
  • 保存FindElement()的返回值,该值是要删除的元素的index
  • 使用它来查看是否找到了要删除的元素。
  • 如果是,请将其传递给DeleteElement()
  • 此外,请编写一个单独的方法来打印列表,而不是在main()中执行两次相同的操作。

以上将帮助您使用您尝试解决问题的方式解决问题。但我确实鼓励你完全重新思考你的方法,因为有更好的方法可以做到这一点。

几点提示:

  • 使用C#集合,例如List<int>而不是传统阵列。
  • 您可以将查找和删除方法合并到一个FindAndDelete()方法中。

希望这有帮助。