【问题标题】:How to find the 2nd largest number in the array, but return the last index that the value appears in?如何找到数组中的第二大数字,但返回该值出现的最后一个索引?
【发布时间】:2016-09-02 01:20:11
【问题描述】:

我的实际问题是在数据集中找到频率第二高的数字。我正在初始化一个数组,它是数据集中最大数字的大小,然后在每次数字出现在数据集中时递增数组中的相应索引。如果两个以上的索引共享第二高频率,那么我需要返回较大的索引。我的代码在某些情况下会返回正确的答案,但不是全部,而且我无法在我的逻辑中找到错误。

int secondFreq(int data[], int maxNum){
    int highest = 0;
    int secondHighest = 0;
    int x;

    for(x = 0; x < maxNum; x++){
        if(data[x] > data[highest]){
            secondHighest = highest;
            highest = x;
        }
        else if (data[x] > data[secondHighest]){
            secondHighest = x;
        }
        else if (data[x] == data[secondHighest]){
            secondHighest = x;
        }
    }

    return secondHighest + 1;
}

这是一个产生错误答案的数组示例。左边的数字是索引,右边的数字是存储在该索引处的值。我的函数返回 12(第 11 个索引 + 1),但它应该返回 5(第 4 个索引 + 1)。

    0 - 2
    1 - 2
    2 - 5
    3 - 2
    4 - 5
    5 - 4
    6 - 2
    7 - 2
    8 - 6
    9 - 4
    10 - 3
    11 - 6
    12 - 2
    13 - 2
    14 - 3

【问题讨论】:

  • 用你的调试器单步调试函数,它会告诉你什么时候变量是错误的。
  • 返回时为什么要给secondHighest加1?
  • 您可以使用&gt;= 组合第二个和第三个if
  • 你能举一个输入产生错误结果的例子吗?
  • 你需要else if (data[x] == data[highest]){ highest = x; }

标签: c arrays math


【解决方案1】:

你的代码有两个问题:

  1. data[x] == data[highest] 的情况下需要设置highest = x;
  2. secondHighest 最初应该处于待处理状态。

以下是修改示例:

int secondFreq(int data[], int maxNum){
    int highest = 0;
    int secondHighest, secondFlag = 0;//secondFlag : Whether secondHighest has been determined, 0 : undetermined, 1(Not 0) : determined
    int x;

    for(x = 1; x < maxNum; x++){
        if(data[x] > data[highest]){
            secondHighest = highest;
            highest = x;
            secondFlag = 1;
        }
        else if (data[x] == data[highest]){
            highest = x;
        }
        else if (secondFlag == 0 || data[x] >= data[secondHighest]){
            secondHighest = x;
            secondFlag = 1;
        }
    }

    if(secondFlag)
        return secondHighest + 1;
    else
        return 0;//All elements same
}

【讨论】:

  • 如果第二个 else if 永远不会执行,这将失败。这发生在上面答案中指出的数据集中:(0 - 2) - (1 - 2) - (2 - 5)
  • 也许我错过了什么。我现在处于 AFK 状态,所以我回家后会检查。
  • 发现错误!我只是错过了您在第一个 if 语句中将 secondFlag 设置为 1。它现在完美运行。谢谢你帮我解决这个问题。
【解决方案2】:

在您的示例中,第二个“6”(索引 11)将转到“else if (data[x] > data[secondHighest])”并将“secondHighest”更新为与“highest”相同。这个逻辑不能处理有多个最高值的情况。 要解决此问题,您可以在其他 'else if' 之前放置一个 'else if(data[x] == data[highest])'。

但是,如果您的数据集如下所示,您将得到另一个错误的答案:

0 - 2
1 - 2
2 - 5

我会将代码更改为更清晰易读,如下所示:

int secondFreq(int data[], int maxNum){
    int secondLargestValue = findsecondLargestValue(data);
    return findIndexofValue(data, secondLargestValue) + 1;
}

int findsecondLargestValue(int data) {
    ...
}

int findIndexofValue(int data, int value) {
    ...
}

【讨论】:

  • 我进行了更改以添加新的 elseif 语句。然后我尝试了您提供的数据集,我的函数返回 2(第一个索引 + 1),这将是正确的答案。我对代码所做的另一项更改是让 secondHighest 未初始化。
【解决方案3】:

如果不是因为 2 pass 的效率考虑,(所以这不是最好的答案),我想说的是:

int secondFreq(int data[], int maxNum)
{
    double          highestVal = data[0];   // start with the first
                        // entry
    int             secondHighest = -1; // will send back 0 if everything
                    // ties for first
    int             x;      // for loop index

    for (x = 1; x < maxNum; x++) {
    if (data[x] > highestVal) {
        highestVal = data[x];
    }
    };
    for (x = 1; x < maxNum; x++) {
    if (data[x] != highestVal)
        &&((secondHighest == -1) || (data[x] >= data[secondHighest])) {
        secondHighest = x;
        }
    }


    return secondHighest + 1;
}

虽然它确实会看两次,但更难搞砸。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    相关资源
    最近更新 更多