排序和删除向量中的重复项<vectors< double>>
Posted
技术标签:
【中文标题】排序和删除向量中的重复项<vectors< double>>【英文标题】:sorting and removing duplicates from a vector<vectors< double> > 【发布时间】:2014-02-20 16:04:40 【问题描述】:您好,我知道有一些类似的问题,但我无法解决我的问题。 我需要在笛卡尔坐标的球体上生成一组独特的点,即从球形转换为笛卡尔坐标。当我这样做时,我将点存储在向量的向量中。但是,创建了一些重复项并删除它们,我尝试使用排序擦除和独特功能。问题是 sort 看不到对我的整个向量进行排序,我不明白为什么?它适用于我只是将数字推回的向量向量,但不适用于我的笛卡尔函数生成的向量向量。我知道这很简单,我已经被困 3 天了,我敢肯定它正盯着我看!!!代码和输出如下
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stdio.h>
int main(int argc, const char * argv[])
std::vector<double> locations; //center of the bubble
locations.push_back(1.0);
locations.push_back(1.0);
locations.push_back(1.0);
std::vector<std::vector<double> > points; //set of points to be created around the bubble
double PI=atan(1)*4;
for(int dr=1; dr<2; dr++)
for (int phi=0; phi<180; phi+=90)
for (int theta=0; theta<360; theta+=90)
std::vector<double> row;
double x=locations[0]+(dr*sin(theta*(PI/180))*cos(phi*(PI/180)));
double y=locations[1]+(dr*cos(theta*(PI/180)));
double z=locations[2]+(dr*sin(theta*(PI/180))*sin(phi*(PI/180)));
row.push_back(x);
row.push_back(y);
row.push_back(z);
points.push_back(row);
std::sort(points.begin(), points.end()); //sort points
std::cout<<"sorted points \n";
for (int i =0; i<points.size(); i++)
std::cout<<points[i][0]<<" "<<points[i][1]<<" "<<points[i][2]<<"\n";
points.erase(std::unique(points.begin(), points.end()), points.end()); //erase duplicates
std::cout<<"duplicates removed \n";
for (int i =0; i<points.size(); i++)
std::cout<< points[i][0]<<" "<<points[i][1]<<" "<<points[i][2]<<"\n";
输出
sorted points
0 1 1
1 1 0
1 0 1 THIS HASN'T BEEN SORTED CORRECTLY
1 1 2
1 2 1
1 2 1
1 0 1 THIS HASN'T BEEN SORTED CORRECTLY
2 1 1
duplicates removed
0 1 1
1 1 0
1 0 1
1 1 2
1 2 1
1 0 1
2 1 1
【问题讨论】:
是的,浮点比较很痛苦。for(int dr=1; dr<2; dr++)
你不需要循环。你只需要const int dr = 1;
。
我建议创建一个封装点方面的类/结构。然后你可以重载运算符来进行排序和比较。这将使您更容易看到您正在尝试执行的操作。
你认为这个比较有什么意义?你是怎么知道1 0 1 THIS HASN'T BEEN SORTED CORRECTLY
的?点0,1,1
、1,1,0
、1,0,1
如何彼此小于或大于彼此?编译器如何知道你的确切意思?
您好,感谢您的建议,我意识到在此示例中我不需要 dr 循环,但这只是最简单的版本,因此问题很清楚。在最终代码中,对于 theta 和 phi,我需要每 10 度 3 个 dr 步骤和点。我担心为点创建结构是一种效率问题。实际代码需要这样做几百次,然后我需要使用这些点来计算穿过球体的通量。
【参考方案1】:
如果换行:
std::cout << points[i][0] << " " << points[i][1] << " " << points[i][2] << "\n";
with(你还需要包括<limits>
和<iomanip>
):
std::cout << std::fixed << std::setprecision(std::numeric_limits<double>::digits10+2) << points[i][0] << " " << points[i][1] << " " << points[i][2] << "\n";
你会看到输出是:
sorted points
0.00000000000000000 0.99999999999999978 1.00000000000000000
0.99999999999999989 0.99999999999999978 0.00000000000000000
1.00000000000000000 0.00000000000000000 1.00000000000000022
1.00000000000000000 1.00000000000000000 2.00000000000000000
1.00000000000000000 2.00000000000000000 1.00000000000000000
1.00000000000000000 2.00000000000000000 1.00000000000000000
1.00000000000000022 0.00000000000000000 1.00000000000000000
2.00000000000000000 1.00000000000000000 1.00000000000000000
duplicates removed
0.00000000000000000 0.99999999999999978 1.00000000000000000
0.99999999999999989 0.99999999999999978 0.00000000000000000
1.00000000000000000 0.00000000000000000 1.00000000000000022
1.00000000000000000 1.00000000000000000 2.00000000000000000
1.00000000000000000 2.00000000000000000 1.00000000000000000
1.00000000000000022 0.00000000000000000 1.00000000000000000
2.00000000000000000 1.00000000000000000 1.00000000000000000
因此考虑近似值向量已正确排序。
PS 您可以在 std::sort()
调用中使用自定义比较器,在 std::unique
调用中使用自定义二进制谓词。
【讨论】:
那么,您认为这个问题会得到解决吗,例如,将double
替换为int
?
@Drop 是的,我认为是这样(至少在具体示例中)。
哦,我明白了!我有一种感觉,这与 PI 的近似值有关。好的,因为我无法更改为int
,因为在实际代码中我需要每 10 度我会按照你的建议尝试,非常感谢!!以上是关于排序和删除向量中的重复项<vectors< double>>的主要内容,如果未能解决你的问题,请参考以下文章