C++ 如何在C++;(不使用C+;+;11)
我试图构造一个函数take获取一个向量,对它进行排序,排序,并输出排序后的向量和值的原始位置。例如:输入:[10332,42,0.9,0]输出:[3,5,4,2,1] 我使用这个堆栈溢出(特别是马吕斯的答案)作为参考指南,但是我现在仍然坚持使用我的代码,不明白问题出在哪里。 我正在运行一个C++03 我犯的一个错误是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
错误:在我的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中的优势,采用一种更健壮的解决方案。为此,我们首先制作一个“索引向量”,即astd::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;
}