【问题标题】:C++ Insertion Sort Median Calculation ErrorC++ 插入排序中位数计算错误
【发布时间】:2012-06-10 06:40:54
【问题描述】:

我遇到了一个我以前从未见过的错误,它指出对事物的引用不明确。

我正在编写一个计算运行中位数的小型测试程序。随着列表的增长,它会重新计算中位数。在这种情况下,中位数表示列表中的中间数字(或上中)。因此,7 的中位数为 7,7 和 9 的中位数为 9,7 3 和 9 的中位数为 7。

我用两个动态数组来完成这个(我希望)。最初,将第一个值设置为中位数,然后将输入的每个数字与当前中位数进行比较。中值用于计算两个数组之间的中间元素。

左侧数组用于所有小于中位数的值,右侧数组用于所有大于中位数的值。我使用插入排序来对每个数组中的数字进行排序(这在几乎排序的列表中非常有用)。

我只是不明白我遇到的错误和哪里出了问题。我对 C++ 还很陌生,所以我选择了一种更简单的方法来解决这个问题。

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector<int> left;
vector<int> right;
int leftCount = 0;
int rightCount = 0;
void leftInsertionSort(int);
void rightInsertionSort(int);
void inputNumber(int, int);

int main(int argc, char** argv) {

    int length = 0;
    int value;
    int median;
    string input;

    while (cin >> input) {
        value = atoi(input.c_str());

        inputNumber(value, median);

        if (leftCount > rightCount) {
            median = (((leftCount + rightCount) / 2) + 1);
            cout << left[median];
        } else {
            median = (((leftCount + rightCount) / 2) + 1) - leftCount;
            cout << right[median];
        }
    }

    return 0;
}

void inputNumber(int value, int median) {
    if (leftCount == 0 && rightCount == 0) {
        left[0] = value;
        median = value;
        leftCount++;
    } else
    if (leftCount == 1 && rightCount == 0) {
        right[0] = value;
        if (left[0] > right[0]) {
            right[0] = left[0];
            left[0] = value;
        }
        median = right[0];
        rightCount++;
    } else
    if (value < median) {
        left[leftCount] = value;
    } else {
        right[rightCount] = value;
    }
}

void leftInsertionSort(int lLength)
{
    leftCount++;
    int key, i;
    for(int j = 1; j < lLength; j++)
    {
        key = left[j];
        i = j - 1;
        while (left[i] > key && i >= 0) {
            left[i+1] = left[i];
            i--;
        }
        left[i+1] = key;
    }
}

void rightInsertionSort(int rLength)
{
    rightCount++;
    int key, i;
    for(int j = 1; j < rLength; j++)
    {
        key = right[j];
        i = j - 1;
        while (right[i] > key && i >= 0) {
            right[i+1] = right[i];
            i--;
        }
        right[i+1] = key;
    }
}

我似乎得到的错误是'错误:对'left'的引用不明确'

【问题讨论】:

  • 错误:对“左”的引用不明确
  • 我也一样
  • 您有什么理由不使用std::multiset?这将为您订购号码。
  • 我认为也存在算法错误。正确的算法是: 1. 根据与中位数的比较插入新元素到正确的数组; 2. 保持数组大小几乎相同 - 如果插入后的一个数组在两个元素中大于另一个数组,则将对应的元素移动到另一个数组

标签: c++ median insertion


【解决方案1】:

从我在尝试编译它时遇到的编译器错误来看,似乎命名空间std 定义了名称leftright,您也将它们用作变量名。编译器无法决定使用哪个定义,因此您会收到错误消息。正是由于这些原因,从命名空间导入所有内容是不受欢迎的——最好是显式导入所需的名称或使用命名空间限定符。

无论如何,您的算法似乎不必要地复杂。为什么不只保留一个向量 push_back 当你得到一个新数字时,使用插入算法将数字放在正确的索引处,然后只返回向量的中上部元素?

【讨论】:

    【解决方案2】:

    leftrightiostream 中的标志。

    只需重命名变量即可。

    【讨论】:

      【解决方案3】:

      这是一个很好的例子,说明为什么#using namespace std 不是一个好主意。 leftright 也是为 std 命名空间定义的,现在存在冲突。如果您省略该行并通过使用std:: 显式指定它们的命名空间来引用向量、字符串、cin 和 cout,您将不会遇到此冲突。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-03
        相关资源
        最近更新 更多