控制台程序移植到MFC下的问题

earth36 2007-06-05 04:13:14
需要把控制台的程序变成MFC对话框程序,希望能按个BUTTON 让输出的结果显示在EDIT中,(能不用数组吗?)下附KMEANS.CPP MAIN.CPP
望达人帮助。

kmeans.cpp
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include "point.h"
#include "kmeans.h"
#include "cluster.h"
#include <time.h>

const int KMeans::maxIters = 250;
const float KMeans::convergenceThreshold = 0.00001;
const int KMeans::numKMeans = 10;
const long KMeans::seed = 123454321;


KMeans::KMeans(char* s ) : s(s) {
DataFp = NULL;
srand(seed);
numIters = 0;
numPoints = 0;

// 读文件S的第一行,这里声明了所有点的维度。
if ((DataFp = fopen( s, "r")) == NULL) {
perror("Unable to open data file ");
std::cout << s << std::endl;
exit(1);
}

fscanf(DataFp, "%i", &dimensions);
//数据的首要信息就是数据点的ID!!!
data = new float[dimensions];
means = new float[dimensions];
stdev = new float[dimensions];

for(int i = 0; i < dimensions; i++) {
means[i] = 0;
stdev[i] = 0;
}

readPoints();
}

/**
* 在向量中选择预置点
*/
void KMeans::initClusters (void) {
//选择任意点
clusters.clear();

int *randNums = new int[numClusters];

for(int i = 0; i < numClusters; i++) {
int random = rand()%numPoints;
for (int j = 0; j < i; j++) {
if (random == randNums[j]) {
i--;
continue;
}
randNums[i] = random;
}
Point* randpoint = points[random];
Cluster *c = new Cluster(dimensions, randpoint->copy(), i);
clusters.push_back(c);
}
}

/**
* 读取文本文件中的点,预置S向量'points'
*/
void KMeans::readPoints (void) {

Point *p;

while ((p = getPoint()) != NULL) {
numPoints++;
points.push_back(p);
}
if (numPoints == 0) {
printf("No points in %s\n", s);
exit(0);
}
standardizePoints();
}

/**
* 读取文件数据
*/
Point* KMeans::getPoint(void) {
float tmp;
float ID;

//标记点
if ((fscanf(DataFp, "%f", &tmp) != 1)) {
return NULL;
} else {
ID = tmp;
}

for (int i = 0; i < dimensions; i++) {
if ((fscanf(DataFp, "%f", &tmp) != 1)) {
return NULL;
} else {
means[i] += tmp;
data[i] = tmp;
}
}

Point *p = new Point(dimensions);
p->init(ID, data);
return p;
}

/**
* 返回读取点的个数
*/
int KMeans::getNumPoints(void) {
return numPoints;
}

/**
* 返回P最接近的点,P非NULL
*/
int KMeans::closestCluster(Point *p) {
float lowestDist = -1;
int closestCluster = 0;

for (int i = 0; i < numClusters; i++) {
Cluster *c = clusters[i];
float dist = c->distanceSquared(p);
if (lowestDist == -1) {
lowestDist = dist;
} else if (dist < lowestDist) {
lowestDist = dist;
closestCluster = i;
}
}
return closestCluster;
}



KMeans::~KMeans() {
for (int i = 0; i < numPoints; i++) {
delete(points[i]);
}
}

/**
* 返回包含所有点的向量
*/
std::vector<Point*> KMeans::getPoints(void) {
return points;
}

/**
* 迭代Kmeans算法.
*/
void KMeans::iterate (void) {
numChanges = 0; //在这次迭代中类成员变化情况

for(int i = 0; i < numClusters; i++) {
clusters[i]->refresh();
}

for (i = 0; i < numPoints; i++) {
Point *curpoint = points[i];
int clusterNum = closestCluster(curpoint);
if(curpoint->getClusterNum() != clusterNum) {
numChanges++;
curpoint->setClusterNum(clusterNum);
}
clusters[clusterNum]->addPoint(curpoint);
}

for(i = 0; i < numClusters; i++) {
clusters[i]->calculateMeans();
}
}

/**
* 返回在最大迭代中成员在类中的变化情况
*/
int KMeans::getNumChanges(void) {
return numChanges;
}

/**
* 连带类情况,输出所有点
*/
void KMeans::outputPoints (void) {
for (int i = 0; i < numPoints; i++) {
points[i]->print();
}
}

/**
* 执行一个K类的点集
*/
void KMeans::doCluster(int k) {

numClusters = k;
float minError = -1;
int *clusterInfo = new int[numPoints];

if (numPoints <= numClusters)
numClusters = numPoints;

//执行算法返回一个最优的
for(int j = 0; j < numKMeans; j++) {

initClusters();

//算法运行直到算法收敛

float prevError = -1; //迭代出错
for (numIters = 0; numIters < maxIters; numIters++) {
iterate();

if (prevError == -1)
prevError = sumErrors();
else if ( getNumChanges() == 0 ||
prevError - sumErrors() < convergenceThreshold) {
break;
}
}

//最好类的信息

float sum = sumErrors();

//printf("number of changes is %i\n", getNumChanges());
//printf("number of iterations is %i\n", numIters);
if (minError == -1 || sum < minError) {
minError = sum;
for(int i = 0; i < numPoints; i++) {
clusterInfo[i] = points[i]->getClusterNum();
}
}
}

//重建最佳类

for (int i = 0; i < numClusters; i++) {
clusters[i]->refresh();
}

for (i = 0; i < numPoints; i++) {
clusters[clusterInfo[i]]->addPoint(points[i]);
}

for (i = 0; i < numClusters; i++) {
clusters[i]->print();
printf ("\n");
}
}

/**
* 计算方差和
*/
float KMeans::sumErrors(void) {
float sumError = 0;
for (int i = 0; i < numClusters; i++)
sumError += clusters[i]->calculateError();
return sumError;
}

/* 反回一个数的绝对值 */

float KMeans::absolute(float x) {
if (x < 0 )
return -x;
else
return x;
}

/**
* 标准化所有的点
*/
void KMeans::standardizePoints() {

//计算均值
for (int i = 0; i < dimensions; i++) {
means[i] = means[i]/numPoints;
}

//计算标准方差 (actually the mean absolute
//deviation which is sum(Xi - Mi)/n
float *tmpdata;
for(i = 0; i < numPoints; i++) {
tmpdata = points[i]->getData();
for (int j = 0; j < dimensions; j++) {
stdev[j] += absolute(tmpdata[j] - means[j]);
//绝对差平均化
/* stdev[j] += pow((tmpdata[j] - means[j]), 2); //偏差标准化 */
}
}

//计算偏差
for (i = 0; i < dimensions; i++) {
stdev[i] = stdev[i]/numPoints; //mean absolute deviation
/* stdev[i] = pow(stdev[i], 0.5)/(numPoints - 1); //standard deviation */
}

//标准化数据
for(i = 0; i < numPoints; i++) {
tmpdata = points[i]->getData();
for(int j = 0; j < dimensions; j++) {
if (stdev[j] == 0) {
//类中没变量,0输出
tmpdata[j] = 0;
} else {
tmpdata[j] = (tmpdata[j] - means[j]) / stdev[j];
}
}
}


}
main.cpp
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "kmeans.h"
#include "point.h"

int main(int argc, char *argv[]) {

char* s = argv[1];
int numClusters = atoi(argv[2]);

KMeans *km = new KMeans ( s );
km->doCluster(numClusters);
}
...全文
356 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
earth36 2007-06-07
  • 打赏
  • 举报
回复
试了快一天了,狂多错,有达人帮忙改改吗? 我这方面实在不怎么样,谢谢了啊!
妍妍 2007-06-06
  • 打赏
  • 举报
回复
还是自己改改吧,这个也没什么难的,关键就是别懒
earth36 2007-06-06
  • 打赏
  • 举报
回复
有人能帮我把代码改改吗?
leibniz_zsu 2007-06-05
  • 打赏
  • 举报
回复
其实要把控制台程序移植到MFC下主要修改的只是输出方式,
可建立一个MFC EXE的项目,再将你的代码加入到项目当中(要加入一些预编译语句).
关键是修改你的程序的输出方式,即在按键的响应程序当中,要将结果输出到EDIT中.
ws22xj 2007-06-05
  • 打赏
  • 举报
回复
MFC中 你把所有的代码都放到到MianDlg.cpp中(你的MFC文件名是main),具体语法和控制台一样,而且有个类叫CMainDlg他就是和你建立的对话框是对应的
然后就拖控件,,用事件响应函数把得到的结果帮到EDIT中
redboot 2007-06-05
  • 打赏
  • 举报
回复
学习

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧