我是C ++的新手。我写了一些代码,但是当我运行它时,总会有这样的代码:
引发异常类 EAccessViolation,消息为“Access” 违反地址'
我不明白这一点。你想帮我解决一下吗?这对我很重要。真的,非常感谢你!
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <math.h>
#include <conio.h>
#define k 2
#define minoffset 0.5
using namespace std;
struct Point
{
double X;
double Y;
};
vector<Point> dataprocess();
void k_means(vector<Point> points,int N);
double getdistance(Point p1,Point p2)
{ double distance;
distance=sqrt((p1.X-p2.X)*(p1.X-p2.X)+(p1.Y-p2.Y)*(p1.Y-p2.Y));
return distance;
}
int getmindis(Point p,Point means[])
{
int i;
int c;
double dis=getdistance(p,means[0]);
for(i=1;i<k;i++)
{
double term=getdistance(p,means[i]);
if(term<dis)
{
c=i;
dis=term;
}
}
return c;
}
Point getmeans(vector<Point> points)
{
int i;
double sumX,sumY;
Point p;
int M=points.size();
for(i=0;i<M;i++)
{
sumX=points[i].X;
sumY=points[i].Y;
}
p.X=sumX/M;
p.Y=sumY/M;
return p;
}
int main()
{ int N;
vector<Point> stars;
stars=dataprocess();
N=stars.size();
cout<<"the size is:"<<N<<endl;
k_means(stars,N);
getch();
}
vector<Point> dataprocess()
{
int i;
int N;
double x,y;
vector<Point> points;
Point p;
string import_file;
cout<<"input the filename:"<<endl;
cin>>import_file;
ifstream infile(import_file.c_str());
if(!infile)
{
cout<<"read error!"<<endl;
}
else
{
while(infile>>x>>y)
{
p.X=x;
p.Y=y;
points.push_back(p);
}
}
N=points.size();
cout<<"output the file data:"<<endl;
for(i=0;i<N;i++)
{
cout<<"the point"<<i+1<<"is:X="<<points[i].X<<" Y="<<points[i].Y<<endl;
}
return points;
}
void k_means(vector<Point> points,int N)
{
int i;
int j;
int index;
vector<Point> clusters[k];
Point means[k];
Point newmeans[k];
double d,offset=0;
bool flag=1;
cout<<"there will be"<<k<<"clusters,input the original means:"<<endl;
for(i=0;i<k;i++)
{
cout<<"k"<<i+1<<":"<<endl;
cin>>means[i].X>>means[i].Y;
}
while(flag)
{
for(i=0;i<N;i++)
{
index=getmindis(points[i],means);
clusters[index].push_back(points[i]);
}
for(j=0;j<k;j++)
{
newmeans[j]=getmeans(clusters[j]);
offset=getdistance(newmeans[j],means[j]);
}
if(offset>d)
{
d=offset;
}
flag=(minoffset<d)?true:false;
for(i=0;i<k;i++)
{
means[i]=newmeans[i];
clusters[i].clear();
}
}
for(i=0;i<k;i++)
{
cout<<"N"<<i+1<<"="<<clusters[i].size()<<endl;
cout<<"the center of k"<<i+1<<"is:"<<means[i].X<<" "<<means[i].Y<< endl;
}
}
答案 0 :(得分:1)
你的代码肯定有一些算法错误。没有输入数据就很难处理导致错误的代码,但让我们试试:
Point getmeans(vector<Point> points)
应该评估点群集的平均坐标:如果将空簇传递给此函数,则会导致错误:
看这里 -
int M=points.size()
在这里 -
for(i=0;i<M;i++)
{
sumX=points[i].X;
sumY=points[i].Y;
}
如果你的集群是空的,那么M
将为零,你循环将迭代2 ^ 31次(直到32位整数溢出),并且每次你将尝试读取不存在的矢量项的值
所以,你必须在运行main函数循环之前测试vector是否为空,并且你必须决定应该为零簇分配哪些平均值(可能你需要一个额外的标志用于空集群,它将在之前检查过处理集群的平均值)
int getmindis(Point p,Point means[])
函数,以及一个我们称之为的地方:
index=getmindis(points[i],means); clusters[index].push_back(points[i]);
此功能可指向群集。簇号由c
变量控制。如果输入点不适合任何集群,函数将返回未初始化的变量(保持任何可能的值)。然后用作不存在元素的向量索引 - 可能的访问冲突错误
您可能必须在声明
中将c
初始化为零
告诉我们您何时准备好上述错误,并向我们展示一个示例输入文件(一个导致错误的文件,如果所有数据集都会导致错误,请向我们展示最小的错误)