【问题标题】:Developing two different algorithms for finding a certain element in an array开发两种不同的算法来查找数组中的某个元素
【发布时间】:2019-01-29 05:39:49
【问题描述】:

我目前正在使用 Java 进行算法开发,最近确实陷入了一个特定问题。我一直面临开发两种不同算法的挑战。

我的任务是解决选择问题。选择问题确定一组 N 个数中第 k 个最大的数。

我已经成功实现了第一个算法。我将N个数字读入一个数组,通过一些简单的算法对数组进行降序排序,然后返回位置k的元素。

注意:k = N / 2

这是工作代码

public int selectionAlgorithmOne() {

    int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};

    //I sort the array of size N in decreasing order 
    bubbleSortDecreasingOrder(intArray);
    //{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}

    //I obtain the value of k
    int k = intArray.length / 2;

    //I print the result
    System.out.println(intArray[k]);
}

5”中打印的值是正确的!然而,第二种算法有点棘手。

将前 k 个元素读入一个数组并按降序对它们进行排序。接下来,一个一个地读取每个剩余的元素。当一个新元素到达时,如果它小于数组中的第 k 个元素,则将其忽略。否则,它将被放置在数组中的正确位置,将一个元素从数组中剔除。当算法结束时,返回第 k 个位置的元素作为答案。

不幸的是,我的第二个算法不起作用。它返回错误的值“3”。它应该返回与第一个算法相同的“5”值,但效率更高。

我已经被困了几天,我真的很难找到解决方案。希望我已经为问题提供了足够的背景信息,如果我可以提供更多信息,请告诉我。提前致谢。

这是无效的代码

public int selectionAlgorithmTwo() {

    int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};

    int arrayLength = intArray.length;
    int k = arrayLength / 2;
    int[] firstHalf = new int[k];

    //I read the first half of the elements into an array
    for (int i = 0; i < k; i++) {
        firstHalf[i] = intArray[i];
    }

    //I then sort the first half of the elements in decreasing order
    bubbleSort(firstHalf);

    for(int i = k; i < arrayLength; i++) {
        int val = intArray[i];

    //If the new element to insert is >= the kth largest
        if (val > firstHalf[k - 1]) {
            int pos = 0;
            for(; pos < k; pos++) {
                if(val > firstHalf[pos]) {
                    break; //I break once I have the correct position located
                }
    //I make the swap
                for (int j = k - 1; j > pos; j--)
                    firstHalf[j] = firstHalf[j - 1];
                firstHalf[pos] = val;
            }
        }
    }
    return firstHalf[k - 1];
}

【问题讨论】:

  • 只是速写,我感觉这个if(val &gt; firstHalf[pos])应该是if(val &lt; firstHalf[pos])
  • 谢谢你。不幸的是,该算法返回值 10 而不是预期的 5。
  • 请在函数结束时以及前半部分刚刚被填充和排序时显示两个数组的内容。
  • 请将其转为minimal reproducible example,并提供有关紧急情况下阵列状态的其他信息。
  • 我认为第二个 for 循环不应该嵌套在第一个中。

标签: java arrays algorithm sorting


【解决方案1】:

首先,“位置 k 的元素”不是第 k 个元素,而是第 k+1 个元素。实际上 5 是排序数组的第六个元素。
所以,如果你想返回位置 k 的元素,你需要一个 k+1 元素的数组。 因此我添加了firstHalfLen 变量。
如果你使用一个 k 元素的数组,你永远不会得到 5 作为答案。

if (val &gt; firstHalf[k])块中,为了找到正确的索引,我更喜欢while循环

while ((pos < firstHalfLen) && (val <= firstHalf[pos])) {
    pos++;
}

然后交换:

for (int j = k; j > pos; j--) {
    firstHalf[j] = firstHalf[j - 1];
}  

代码:

int[] intArray = new int[] { 1, 7, 9, 8, 2, 3, 5, 4, 6, 10 };

int arrayLength = intArray.length;
int k = arrayLength / 2;
int firstHalfLen = k + 1;
int[] firstHalf = new int[firstHalfLen];

// I read the first half of the elements into an array
for (int i = 0; i < firstHalfLen; i++) {
    firstHalf[i] = intArray[i];
}

//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);

for (int i = firstHalfLen; i < arrayLength; i++) {
    int val = intArray[i];

    // If the new element to insert is >= the kth largest
    if (val > firstHalf[k]) {
        int pos = 0;
        // find index
        while ((pos < firstHalfLen) && (val <= firstHalf[pos])) {
            pos++;
        }

        // Swap
        for (int j = k; j > pos; j--) {
            firstHalf[j] = firstHalf[j - 1];
        }
        firstHalf[pos] = val;

    }
}

return firstHalf[k];

【讨论】:

  • 漂亮!非常感谢您。
【解决方案2】:

您正在将未排序部分的值与已排序部分的值进行比较,从低位开始,即小值。该值大于第一个排序值的概率非常高。更有趣的是更小的值。根据您的算法,较小的未排序值应插入到较小的排序值中,在它替换较高值的位置,而不是较小的值。

所以

if(val > firstHalf[pos])  

应该是

if(val < firstHalf[pos])

【讨论】:

  • 在进行更改后,我添加了一个打印语句来打印“firstHalf”。在算法结束时,firstHalf 包含值 [10,10,10,10,10]。
  • 请在函数的末尾显示两个数组的内容在前半部分刚刚被填充和排序的时候。在问题中这样做,而不是在对答案的评论中这样做,以便获得更多空间和更有用的格式。
【解决方案3】:

试试这个代码:

public int sortTest() {
    int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};

    int arrayLength = intArray.length;
    int k = arrayLength / 2;
    int[] firstHalf = new int[k];

    //I read the first half of the elements into an array
    for (int i = 0; i < k; i++) {
        firstHalf[i] = intArray[i];
    }

    //I then sort the first half of the elements in decreasing order
    bubbleSort(firstHalf);

    for(int i = k; i < arrayLength; i++) {
        int val = intArray[i];

        //If the new element to insert is >= the kth largest
        if (val > firstHalf[k - 1]) {
            int pos = 0;
            for(; pos < k; pos++) {
                if(val > firstHalf[pos]) {
                    break; //I break once I have the correct position located
                }
            }
            //I make the swap
            for (int j = k - 1; j > pos; j--)
                firstHalf[j] = firstHalf[j - 1];
            firstHalf[pos] = val;

        }
    }
    return firstHalf[k - 1];
}

您的代码中的错误是,在您找到正确的位置并中断后,您离开了 for 循环而没有交换过程。

还请注意,此代码返回 6,而不是 5,因为您返回了第 k-1 个值。

【讨论】:

    猜你喜欢
    • 2017-04-21
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多