我是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;
}
}
您的代码中肯定有一些算法错误。没有输入数据的代码很难处理,这会导致错误,但让我们试试:
- 首先,让我们看看函数
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函数循环之前,你必须测试你的向量是否为空,你必须决定应该为零集群分配哪些平均值(可能你需要一个额外的空集群标志,在处理集群的平均值之前检查)
- 然后让我们检查函数
int getmindis(Point p,Point means[])
,也,一个地方,我们调用它:index=getmindis(points[i],means); clusters[index].push_back(points[i]);
这个函数将点赋给集群。簇数由c
变量决定。如果输入点不适合任何集群,函数将返回未初始化的变量(包含任何可能的值)。Then用作不存在元素的向量索引——可能的访问冲突错误
你可能需要在声明
中将c
初始化为0告诉我们什么时候你会准备好上面描述的错误,并向我们展示一个示例输入文件(一个导致错误,如果所有数据集导致错误,给我们展示最小的一个)