Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C++;(不使用C+;+;11)_C++_Sorting_Indexing_Rank_C++03 - Fatal编程技术网

C++ 如何在C++;(不使用C+;+;11)

C++ 如何在C++;(不使用C+;+;11),c++,sorting,indexing,rank,c++03,C++,Sorting,Indexing,Rank,C++03,我试图构造一个函数take获取一个向量,对它进行排序,排序,并输出排序后的向量和值的原始位置。例如:输入:[10332,42,0.9,0]输出:[3,5,4,2,1] 我使用这个堆栈溢出(特别是马吕斯的答案)作为参考指南,但是我现在仍然坚持使用我的代码,不明白问题出在哪里。 我正在运行一个C++03 我犯的一个错误是 错误:在我的if语句中,数组下标的“const float*[float]”类型无效 //Rank the values in a vector std::vector<fl

我试图构造一个函数take获取一个向量,对它进行排序,排序,并输出排序后的向量和值的原始位置。例如:输入:[10332,42,0.9,0]输出:[3,5,4,2,1]

我使用这个堆栈溢出(特别是马吕斯的答案)作为参考指南,但是我现在仍然坚持使用我的代码,不明白问题出在哪里。 我正在运行一个C++03

我犯的一个错误是

错误:在我的
if
语句中,数组下标的“const float*[float]”类型无效

//Rank the values in a vector
std::vector<float> rankSort(const float *v_temp, size_t size)
{
    vector <float> v_sort;
    //create a new array with increasing values from 0 to n-1
    for(unsigned i = 0; i < size; i++)
    {
        v_sort.push_back(i);
    }
    bool swapped = false;
    do
    {
        for(unsigned i = 0; i < size; i++)
        {
            if(v_temp[v_sort[i]] > v_temp[v_sort[i+1]]) //error line
            {
                float temp = v_sort[i];
                v_sort[i] = v_sort[i+1];
                v_sort[i+1] = temp;
                swapped = true;
            }
        }
    }
    while(swapped);
    return v_sort;
}

std::vector<float> rankSort(const std::vector<float> &v_temp)
{
    return rankSort(&v_temp[0], v_temp.size());
}
//对向量中的值进行排序
标准::向量rankSort(常量浮点*v_temp,size_t size)
{
向量v_排序;
//创建一个值从0增加到n-1的新数组
for(无符号i=0;iv_temp[v_sort[i+1]])//错误行
{
浮动温度=v_排序[i];
v_排序[i]=v_排序[i+1];
v_排序[i+1]=温度;
交换=真;
}
}
}
while(交换);
返回v_排序;
}
标准::向量rankSort(常数标准::向量和v_temp)
{
返回rankSort(&v_temp[0],v_temp.size());
}

v_sort[i]
是一个
浮点数
(它只是
v_sort
向量的一个元素),而只有整数类型可以用作数组下标

可能您的意思是将
v_sort
作为一个索引数组,因此,您应该将其声明为
std::vector
std::vector
诸如此类

UP:另外,如果您更改了传递的数组的值,那么通过
const
引用传递它并不是一种优雅的方式

总之,以下代码在我的计算机上正确编译:

std::vector<unsigned> rankSort(float *v_temp, size_t size)
{
    vector <unsigned> v_sort;
    //create a new array with increasing values from 0 to n-1
    for(unsigned i = 0; i < size; i++)
    {
        v_sort.push_back(i);
    }
    bool swapped = false;
    do
    {
        for(unsigned i = 0; i < size; i++)
        {
            if(v_temp[v_sort[i]] > v_temp[v_sort[i+1]]) //error line
            {
                unsigned temp = v_sort[i];
                v_sort[i] = v_sort[i+1];
                v_sort[i+1] = temp;
                swapped = true;
            }
        }
    }
    while(swapped);
    return v_sort;
}

std::vector<unsigned> rankSort(std::vector<float> &v_temp)
{
    return rankSort(&v_temp[0], v_temp.size());
}
std::向量rankSort(浮点*v\u temp,size\u t size)
{
向量v_排序;
//创建一个值从0增加到n-1的新数组
for(无符号i=0;iv_temp[v_sort[i+1]])//错误行
{
无符号temp=v_排序[i];
v_排序[i]=v_排序[i+1];
v_排序[i+1]=温度;
交换=真;
}
}
}
while(交换);
返回v_排序;
}
标准::向量rankSort(标准::向量和v_temp)
{
返回rankSort(&v_temp[0],v_temp.size());
}
//在向量中对值进行排序
标准::向量rankSort(常数标准::向量和v_temp)
{
向量v_排序;
//创建一个新数组,将值从0增加到size-1
对于(大小i=0;iv_temp[v_sort[i+1]]
{
size_t temp=v_sort[i];//我们交换索引数组元素,而不是原始数组元素
v_排序[i]=v_排序[i+1];
v_排序[i+1]=温度;
交换=真;
}
}
while(交换);
返回v_排序;
}

你的问题是对排名的误解。数组索引的大小是
size\u t
而不是
float
,因此您需要返回
向量
而不是
向量

也就是说你的排序是O(n2)。如果您愿意使用更多内存,我们可以将时间缩短到O(n log(n)):


我建议您利用STL中的优势,采用一种更健壮的解决方案。为此,我们首先制作一个“索引向量”,即a
std::vector v
,这样对于任何
i
v[i]==i
都是真的:

// I'm sure there's a more elegant solution to generate this vector
// But this will do
std::vector<std::size_t> make_index_vector(std::size_t n) {
    std::vector<std::size_t> result(n, 0);
    for (std::size_t i = 0; i < n; ++i) {
        result[i] = i;
    }
    return result;
}
现在,我们将所有部件组合在一起:

template <typename T, typename A, typename Cmp>
std::vector<std::size_t> make_rank_vector(
    std::vector<T, A> const& vec, Cmp comp) {
    return get_rank_vector(sorted_index_vector(vec, comp));
}

// I had to stop using default template parameters since early gcc version did not support it (4.3.6)
// So I simply made another overload to handle the basic usage.
template <typename T, typename A>
std::vector<std::size_t> make_rank_vector(
    std::vector<T, A> const& vec) {
    return make_rank_vector(vec, std::less<T>());
}
模板
std::向量生成秩向量(
标准::向量常量和向量,Cmp组件){
返回get_rank_vector(排序的索引向量(vec,comp));
}
//我不得不停止使用默认模板参数,因为早期的gcc版本不支持它(4.3.6)
//所以我简单地做了另一个重载来处理基本用法。
模板
std::向量生成秩向量(
标准::矢量常量和矢量){
返回make_rank_vector(vec,std::less());
}
[10332,42,0.9,0]的结果为[3,5,4,2,1]。
您可以在GCC4.3.6上找到一个明确的方法来说明这种行为。

下面是我使用STL的代码,以一种简洁的方式来实现这一点,以获得排名

template <typename T>
vector<size_t> calRank(const vector<T> & var) {
    vector<size_t> result(var.size(),0);
    //sorted index
    vector<size_t> indx(var.size());
    iota(indx.begin(),indx.end(),0);
    sort(indx.begin(),indx.end(),[&var](int i1, int i2){return var[i1]<var[i2];});
    //return ranking
    for(size_t iter=0;iter<var.size();++iter){
        result[indx[iter]]=iter+1;
    }
    return result;
}
模板
向量calRank(常量向量和变量){
向量结果(变量size(),0);
//排序索引
向量indx(变量size());
iota(indx.begin(),indx.end(),0);

排序(indx.begin(),indx.end(),[&var](inti1,inti2){returnvar[i1]你在哪一行得到错误?请用注释等表示。另外,为什么你要传递一个指向排序函数的指针?为什么不在取向量的函数中对它排序?@Someprogrammerdude donelasly,你在内部排序循环中有一个off-by-one错误。当
i==size-1
v\u sort
中的哪个元素将是由
i+1
索引?您使用的是哪种编译器?为什么是C++03?最有可能的是您可以使用的最新版本。例如,Visual Studio在2010年版本中首次提供了C++11功能,在2012年提供了C++14功能。编译器本身可以免费下载原始示例带有数组,因此我尝试将其集成到向量中。无论如何,如果您计划在
v_sort
中存储索引,它应该是一个整数值容器。向量或数组索引0.5没有意义。好的,因此我可以将
v_sort
的类型更改为
int
,而不是
float
,但是错误仍然存在
// I'm sure there's a more elegant solution to generate this vector
// But this will do
std::vector<std::size_t> make_index_vector(std::size_t n) {
    std::vector<std::size_t> result(n, 0);
    for (std::size_t i = 0; i < n; ++i) {
        result[i] = i;
    }
    return result;
}
template <typename T, typename A, typename Cmp>
struct idx_compare {
    std::vector<T, A> const& v;
    Cmp& cmp;
    idx_compare(std::vector<T, A> const& vec, Cmp& comp) : v(vec), cmp(comp) {}

    bool operator()(std::size_t i, std::size_t j) {
        return cmp(v[i], v[j]);
    }
};

template <typename T, typename A, typename Cmp>
std::vector<std::size_t> sorted_index_vector(std::vector<T, A> const& vec, Cmp comp) {
    std::vector<std::size_t> index = make_index_vector(vec.size());
    std::sort(index.begin(), index.end(),
        idx_compare<T, A, Cmp>(vec, comp));

    return index;
}
std::vector<std::size_t> get_rank_vector(std::vector<std::size_t> const& index) {
    std::vector<std::size_t> rank(index.size());
    for (std::size_t i = 0; i < index.size(); ++i) {
        // We add 1 since you want your rank to start at 1 instead of 0
        // Just remove it if you want 0-based ranks
        rank[index[i]] = i + 1;
    }
    return rank;
}
template <typename T, typename A, typename Cmp>
std::vector<std::size_t> make_rank_vector(
    std::vector<T, A> const& vec, Cmp comp) {
    return get_rank_vector(sorted_index_vector(vec, comp));
}

// I had to stop using default template parameters since early gcc version did not support it (4.3.6)
// So I simply made another overload to handle the basic usage.
template <typename T, typename A>
std::vector<std::size_t> make_rank_vector(
    std::vector<T, A> const& vec) {
    return make_rank_vector(vec, std::less<T>());
}
template <typename T>
vector<size_t> calRank(const vector<T> & var) {
    vector<size_t> result(var.size(),0);
    //sorted index
    vector<size_t> indx(var.size());
    iota(indx.begin(),indx.end(),0);
    sort(indx.begin(),indx.end(),[&var](int i1, int i2){return var[i1]<var[i2];});
    //return ranking
    for(size_t iter=0;iter<var.size();++iter){
        result[indx[iter]]=iter+1;
    }
    return result;
}