#问题:
33行
未初始化变量 C::labels。始终初始化成员变量(type.6)。
未初始化变量 C::m_data。始终初始化成员变量(type.6)。
未初始化变量 C::p。始终初始化成员变量(type.6)。
215行,在utility文件中
“初始化”: 从“const _Ty2”转换到“_Ty2”,可能丢失数据。
代码为自己做的knn算法和注释,只是可惜水平有限,不会处理错误。
#include<iostream>
#include<fstream>
#include<vector>
#include<map> //Pair所在头文件
#include<algorithm> //Sort方法头文件
const int row = 12; //178
const int col = 4; //14
class C {
private:
double m_data;
public:
int k;
int labels[row];
double** p;
double TestData[14];
std::vector<std::pair<int, double>>index_distance;
std::map<int, int>LabelPair;
double compute_distance(double* dt1, double* dt2);
void process_distance();
void Highest_Frequency_Label();
struct CmpValue {
bool operator() (const std::pair<int,int>& lhs, const std::pair<int,int>& rhs)
{
return lhs.second < rhs.second;
}
};
C()
{
double** p = new double* [row];
for (int i = 0; i < row; i++) {
p[i] = new double[col];
}
std::ifstream f; // 定义输入文件对象
f.open("E://wine.data", std::ios::in); // 以文本只读方式打开文件
int i, j;
char sep;
if (f) { // 如果文件成功打开…
for (i = 0; i < row; i++) {
for (j = 0; j < 13; j++)
f >> p[i][j] >> sep; // 逐个读入文件数据(逗号读入变量 sep,抛弃不用)
f >> p[i][j]; // 每行最后一个数据后没有逗号,需要单独读取
}
for(int i = 0;i < row;i++)
f >> labels[i];
f.close();
}
std::cout << "请输入测试值的数据:" << std::endl;
for (int n = 0; n < col; n++)
{
std::cin >> TestData[n];
}
std::cout << std::endl;
std::cout << "请指定附近有k个数据被划定范围内:";
std::cin >> k;
};
~C() {
for (int i = 0; i < row; i++)
delete[] p[i];
delete[] p;
}
};
double C::compute_distance(double* dt1, double* dt2)
{
double sum = 0;
for (int i = 0; i < col; i++)
{
sum += pow((dt1[i] - dt2[i]), 2);
}
return (sqrt(sum));
}
void C::process_distance()
{
double distance;
for (int i = 0; i < row; i++)
{
distance = compute_distance(p[i], TestData);
index_distance.emplace_back((i),(distance)); //向动态数组中push pair类型是否正确?
}
}
void C::Highest_Frequency_Label()
{
sort(index_distance.begin(), index_distance.end(),CmpValue());
/*第三个参数不填, 默认sort函数排index_distance为升序。但想要排序正确,需写入结构体
使函数操作于 比较左右值的second(因为动态数组以pair为模板),因为程序的目的是比较second(distance)
排序完返回的动态数组是pair.first乱序(各自属于原来的distance),pair.second为升序
故可以通过labels[]直接索引标签*/
std::cout << "前" << k << "个最小数据排序为:" << std::endl;
for (int i = 0; i < k; i++)
{
//最小值的输出
std::cout
<< "index = " << index_distance[i].first
<< "distance= " << index_distance[i].second
<< "label = " << labels[index_distance[i].first];
LabelPair[labels[index_distance[i].first]]++;
}
/*STL - map自增(map++), map不支持随即访问,map[i]分两步。
1.下标插入:map[i] = 插入key为i 和 value为0的键值对pair<variable1,variable2>(i,0)<---不赋初值时value = 0
2.自加:map[i]++ = 取出key为i的键值对,i不变,其value自增。*/
/*所以map_label[labels[index_distance[i].first]]++; 是指
为每一个标签(共三种)创建一个初始键值对pair(i,0),每当检索到相应标签,其value自增1,比较value大小即可判断标签出现频率*/
std::map<int, int>::iterator it = LabelPair.begin();
int Highest_frequency = 0;
int label;
while (it != LabelPair.end())
{
if (it->second > Highest_frequency)
{
Highest_frequency = it->second;
label = it->first;
}
it++;
}
std::cout << "数据属于标签:" << "label = " << label << std::endl;
}
int main() {
//Scoped_ptr a = new C();
C* b = new C();
b->process_distance();
b->Highest_Frequency_Label();
std::cin.get();
}