C++:一个算法的实现
C++ : Implementation of an algorithm
我正在尝试实现以下算法:
- 创建具有单点P的集合Sp
- 计算Sp中的每个点与其外部的每个点之间的距离,然后将最大距离最小的点添加到Sp
- 重复2。直到Sp具有k个点
- 重复1-3,将每个点作为初始P
- 以最大距离最小的Sp为例
以下是我的代码:
using namespace std;
typedef pair<double,double> pairs ;
#define x first
#define y second
#define INF numeric_limits<double>::infinity();
double dist(double x1,double y1,double x2,double y2)
{
return pow(((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)),1/2);
}
int main()
{
int n,k; // n = total points, k= min points to be included
pairs a[n];
int vis[n]={0};
for(int i=0;i<n;i++)
cin>>a[i].x>>a[i].y;
set< pairs > s;
double ans=INF;
double least=INF;
int id=0;
for(int i=0;i<n;i++)
{
s.clear();
memset(vis,0,sizeof(vis));
while(s.size()<=k) // till set has k points
{
s.insert(a[i]);
vis[i]=1;
for(auto v:s) // every point in set
{
for(int j=0;j<n;j++) // point outside
{
if(!vis[j])
{
double d = dist(v.x,v.y,a[j].x,a[j].y);
if(d<=ans) // compare and find least
{
ans=d;
id=j;
}
}
}
s.insert(a[id]); // add least dist point
if(s.size()>=k)
break;
}
}
least=min(least,ans);
cout<<"least="<<least<<"n";
}
但代码被卡在了需要在集合中插入最小点的位置。它不是插入到Sp的最大距离最小的点。我不知道在实现中是否还有其他错误。
有人能检查一下这个实施并帮助纠正错误吗?
在您的代码中,ans默认设置为-1。如果我没有错的话,这永远不会发生:
if(d<=ans) // compare and find least { ans=d; id=j; }
您只需重复插入[0]。
有人能检查一下这个实现并帮助纠正错误吗?
如果没有一组示例点,很难真正测试代码,但是。。。
(1) 以下部分是极其危险的
int n,k; // n = total points, k= min points to be included
pairs a[n];
int vis[n]={0};
for(int i=0;i<n;i++)
cin>>a[i].x>>a[i].y;
我希望在你的真实代码中有这样的东西
static constexpr int n = <a n value>;
static constexpr int k = <a k value>;
或者至少,对于邪恶的宏,
#DEFINE n <a n value>
#DEFINE k <a k value>
因为,如果您定义了两个具有维度的C样式数组,则在运行时在两个变量中设置
pairs a[n];
int vis[n]={0};
您的代码不是C++标准。
此外,如果没有设置变量(如示例代码中所示),则行为是未定义的(也就是以有趣的方式崩溃)。
如果维度(k
和n
)是在运行时设置的(根据标准输入?),则应该使用几个std::vector
,而不是C样式数组;类似(注意:代码未测试)
int n; // total points
int k; // min points to be included
std::cin >> n; // read n from standard input
std::cin >> k; // read k from standard input
std::vector<pairs> a { n };
std::vector<int> vis { n, 0 };
for ( int i = 0 ; i < n ; ++i )
std::cin >> a[i].x >> a[i].y;
(2) 如果您想退出带有k
点的循环
while(s.size()<=k) // till set has k points
你的while
测试必须是s.size() < k
,而不是s.size() <= k
。
否则,当size()
为k
时,您仍处于循环中,您添加另一个点并使用k+1
点退出
(3) 如果你想重复添加距离设置最小的点,下面的代码
while(s.size()<=k) // till set has k points
{
s.insert(a[i]);
vis[i]=1;
for(auto v:s) // every point in set
{
for(int j=0;j<n;j++) // point outside
{
if(!vis[j])
{
double d = dist(v.x,v.y,a[j].x,a[j].y);
if(d<=ans) // compare and find least
{
ans=d;
id=j;
}
}
}
s.insert(a[id]); // add least dist point
if(s.size()>=k)
break;
}
是错误的,因为
(3a)你没有将ans
初始化为INF(你必须在每个点插入的周期之前初始化它,而不是在程序中只初始化一次)
(3b)必须将点插入for (auto v : s)
循环之外,而不是内部
(3c)当在s
中插入a[id]
时,或者在下一个循环中再次插入相同的id
时,必须设置v[id] = 1
(3d)在每次迭代时,您应该只插入a[i]
一次,在while()
循环之外,而不是在内部,一次又一次
(3e)不是错误,而是。。。您的周期for(auto v:s)
不会修改v
,因此,为了避免不必要的副本,为什么不修改for ( auto const & v : s )
?
(3f)不需要if(s.size()>=k) break;
记住第(2)点,我想你可以写一些类似的东西
s.insert(a[i]);
vis[i] = 1;
while ( s.size() < k ) // till set has k points
{
ans = INF;
for ( auto const & v : s ) // every point in set
{
for ( int j = 0 ; j < n ; ++j ) // point outside
{
if ( ! vis[j] )
{
double d { dist(v.x, v.y, a[j].x, a[j].y) };
if (d <= ans ) // compare and find least
{
ans = d;
id = j;
}
}
}
}
s.insert(a[id]); // add least dist point
v[id] = 1;
}
- 为什么这个选择排序算法仍然切换一个元素,当它已经是其他元素中最小的元素时?
- 一个有效的图算法,满足以下条件
- 什么 STL 算法可以确定容器中的一个项目是否满足谓词?
- 并行算法将向量的元素分配到另一个元素的元素
- STL 算法 + c'tor 不再适用于指向 C 数组的原始指针,因为指向一个过去的末端
- 更好的算法来检查一个数字是否既不是素数也不是单个素数的幂
- C++:一个算法的实现
- 我正在尝试为 Kruskal 算法实现一个C++程序,该程序需要我按权重对图形进行排序。如何按权重对结构进行排序
- 对于这个特定用例来说,一个很好的排序算法
- 需要一个高效的减法算法取模一个数字
- 需要一个好的算法来对8GB的图片进行分类
- 我需要一个测试案例来证明我的算法/代码错误
- 在C 中编写一个简单的排序算法以及伪代码版本
- 有没有一个带有距离标记的最短路径算法的开源实现
- 建议一个合适的算法来合并包含类对象的两个数组(不重复)
- 在正方形矩阵中,每个单元格都是黑色或白色.设计了一个算法来寻找最大白色子平方
- 给定一个二叉树,设计一个算法,创建每个深度的所有节点的链表
- 创建一个算法,要求用户输入两个正数,将它们称为 "first" 和 "last" ,并打印第一个正数之间的所有数字的总和
- 寻找一个算法/类计数IP地址(直方图)
- 这是一个O(n)算法吗?