| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1052 人关注过本帖
标题:求大神帮我改改这个程序 设置可变动大小的数组(大概是关于动态内存分配吧) ...
取消只看楼主 加入收藏
holylightsj
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2013-8-16
结帖率:33.33%
收藏
已结贴  问题点数:20 回复次数:7 
求大神帮我改改这个程序 设置可变动大小的数组(大概是关于动态内存分配吧)
这个是个最小二乘法拟合的程序,通过读取TXT文件里的点坐标来拟合。
因为我设数组什么的只会最基本的方法,所以这里很死板地只能拟合11个点
听说这个跟动态内存分布有关 但是对于这个我完全不会
求大神帮我修改成可以拟合任意个点的程序 多谢
更详细的东西在程序中间有一大段注释

0     0
5     1.27
10    2.16
15    2.86
20    3.44
25    3.87
30    4.15
35    4.37
40    4.51
45    4.58
50    4.02
以上为原始的shuru.txt内容,11个点。

#include "StdAfx.h"
#include<fstream>
#include<math.h>
#include <iomanip>
using namespace std;
double maxB(double array[4]);
double gt(double x[11],double y[11]);
double GS(double a[4][4],double b[4],double e[],double s[], double x[4]/*多项式系数*/);
int  CalculateMinBin(const char *pFilename, double result[4])//因为这个是从直接从MFC里面提出来的 要单独运行的版本我在最后附上
{
    if(!pFilename)
        return -1;
    double a[11]={1,1,1,1,1,1,1,1,1,1,1},b[11],c[11],d[11],e[11],f[10],g[4];
       int i;
    ifstream fin(pFilename);
    if (!fin)
        return 1;
    for(i=0;i<11;i++)//读入n个数据点
    {
        fin>>b[i];fin>>e[i];//左列写入x,右列写入y
        c[i]=b[i]*b[i];//x平方
        d[i]=b[i]*b[i]*b[i];//x立方
    }
    fin.close();//结束输入

  f[0]=gt(a,a);f[1]=gt(a,b);f[2]=gt(a,c);f[3]=gt(a,d);f[4]=gt(b,b);f[5]=gt(b,c);f[6]=gt(b,d);
  f[7]=gt(c,c);f[8]=gt(c,d);f[9]=gt(d,d);g[0]=gt(a,e);g[1]=gt(b,e);g[2]=gt(c,e);g[3]=gt(d,e);
  double array[4][4]={{f[0],f[1],f[2],f[3]},{f[1],f[4],f[5],f[6]},{f[2],f[5],f[7],f[8]},{f[3],f[6],f[8],f[9]}};//生成4*4矩阵
  return GS(array,g,e,b, result);

/*
f[i]
0  1  2  3
1  4  5  6
2  5  7  8
3  6  8  9
array[4][4]   g[i]    e[i]   b[i]     a    b    c       d      e   
aa ab ac ad    ae      y1     x1        
ab bb bc bd    be      y2     x2
ac bc cc cd    ce      y3     x3      1    x   x平方   x立方   y
ad bd cd dd    de      y4     x4
array[4][4]   g[i]    e[i]   b[i]     a    b    c       d      e  
  正定矩阵  右侧矩阵   y值    x值
  关系: 正定矩阵 *多项式系数矩阵=x^n*y 0加到m  n=0-3四次 m=0-10十一项
        array[4][4]*      x[i]      =      g[i]
1     x     x^2   x^3      a0               y
x     x^2   x^3   x^4      a1               y*x
x^2   x^3   x^4   x^5      a2               y*x^2
x^3   x^4   x^5   x^6      a3               y*x^3
x^n为11个x的n次方之和  多项式系数     y*x^n为11个y*x^n的和              y                   x
GS(    double a[4][4],                    double b[4],             double e[11],       double s[11])

解线性方程组。
主对角线优势,使用高斯-赛德尔迭代法求解x[i]


此处拟合算法可以通用,与原始数据点的个数无关。
a[]包含相当于坐标点数量的1,比如a[11]由11个1组成
f[10]包含正定矩阵所有元素,不用改变。
g[4]包含所有右侧矩阵元素,不用改变
要改的地方就是本CPP里所有写着11以及与11有关联的地方
比如所有的?[11]以及各种for(?<11)及相关等
因为希望能读取任意组坐标,所以将11变为可以根据shuru.txt中坐标数量来取值的数。
比如这里都取11,因为shuru.txt里有11个点的坐标。
如果shuru.txt里有12个点坐标,把所有11改成12即可。
但是手动改起来太麻烦,所以想个办法能让他们根据点坐标数量自动取值。
比如shuru.txt里包含有n个点,则自动变为?[n]与for(?<n)
貌似是要使用动态内存分配的方法?

*/
}
double gt(double x[11],double y[11])
{   
    double sum=0;
    for(int i=0;i<11;i++)
       sum=x[i]*y[i]+sum;
     return sum;
}//定义gt,累加之和。
double GS(double a[4][4],double b[4],double e[11],double s[11], double x[4]/*多项式系数*/)
//     GS(  array[4][4]      g[i]         e[i]         b[i]);
{
    double c[4]={0};
    double x0[4]={0};
    int i,k,j;
    double r,sum=0;
    for(k=1;;k++)
    {
        for(i=0;i<4;i++)
        {
            for(j=0;j<4;j++)
            {
                sum=a[i][j]*x0[j]+sum;
            }
              x[i]=x0[i]+(b[i]-sum)/a[i][i];
//       n-1
//x =(d -∑ a  x )/a
// i   i j=0 ij j   ii
              c[i]=fabs(x[i]-x0[i]);//精度
              x0[i]=x[i];
              sum=0;
        }
            r=maxB(c);//转到下一段double max
            if(r<0.00000001)//给定精度要求满足则结束迭代
             {
//                 cout<<"解得的三次拟合曲线系数为:\n";
//                 for(i=0;i<4;i++)
//                 cout<<"A"<<i<<"="<<x[i]<<endl;
                break;
            }
   
    }
    return 0;
}
double maxB(double array[4])
{
    double a=array[0];
    int i;
    for(i=0;i<4;i++)
        if(a<array[i])
            a=array[i];
    return a;//取最大值
}
//////////////////////////////////////////////////
以下是可以单独运行的CPP版本

#include<iostream>
#include<fstream>
#include<math.h>
#include <iomanip>
using namespace std;
double max(double array[4]);
double gt(double x[11],double y[11]);
double GS(double a[4][4],double b[4],double e[],double s[]);
void  main()
{
   double a[11]={1,1,1,1,1,1,1,1,1,1,1},b[11],c[11],d[11],e[11],f[10],g[4];
       int i;
    char strl[10];//存放文件名
    cout<<"\n输入文件名:";//输入位于当前文件夹内的shuru.txt即可。
    cin>>strl;
    ifstream fin(strl);
    if (!fin)
    {cout<<"cant open"<<strl<<endl;exit(1);}
    for(i=0;i<11;i++)//读入n个数据点
    {fin>>b[i];fin>>e[i];//左列写入x,右列写入y
        c[i]=b[i]*b[i];//x平方
    d[i]=b[i]*b[i]*b[i];}//x立方
    fin.close();//结束输入
  f[0]=gt(a,a);f[1]=gt(a,b);f[2]=gt(a,c);f[3]=gt(a,d);f[4]=gt(b,b);f[5]=gt(b,c);f[6]=gt(b,d);
  f[7]=gt(c,c);f[8]=gt(c,d);f[9]=gt(d,d);g[0]=gt(a,e);g[1]=gt(b,e);g[2]=gt(c,e);g[3]=gt(d,e);
  double array[4][4]={{f[0],f[1],f[2],f[3]},{f[1],f[4],f[5],f[6]},{f[2],f[5],f[7],f[8]},{f[3],f[6],f[8],f[9]}};//生成4*4矩阵
  GS(array,g,e,b);
double gt(double x[11],double y[11])
{   
    double sum=0;
    for(int i=0;i<11;i++)
       sum=x[i]*y[i]+sum;
     return sum;
}//定义gt,二者乘积的累加之和。
double GS(double a[4][4],double b[4],double e[11],double s[11])
//     GS(  array[4][4]      g[i]         e[i]         b[i]);
{
    double c[4]={0};
    double x0[4]={0};
    int i,k,j;
    double x[4];//多项式系数
    double r,sum=0;
    for(k=1;;k++)
    {
        for(i=0;i<4;i++)
        {
            for(j=0;j<4;j++)
            {
                sum=a[i][j]*x0[j]+sum;
            }
              x[i]=x0[i]+(b[i]-sum)/a[i][i];
//       n-1
//x =(d -∑ a  x )/a
// i   i j=0 ij j   ii
              c[i]=fabs(x[i]-x0[i]);//精度
              x0[i]=x[i];
              sum=0;
        }
            r=max(c);//转到下一段double max
            if(r<0.00000001)//给定精度要求满足则结束迭代
             {
                cout<<"解得的三次拟合曲线系数为:\n";
                for(i=0;i<4;i++)
                cout<<"A"<<i<<"="<<x[i]<<endl;
                //多项式格式为:A0+A1x+A2x^2+A3x^3=0
                break;
            }
   
    }
    return 0;
}
double max(double array[4])
    {
        double a=array[0];
        int i;
        for(i=0;i<4;i++)
        {if(a<array[i])
                a=array[i];}
    return a;}//取最大值
搜索更多相关主题的帖子: include 动态 
2013-09-25 20:12
holylightsj
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2013-8-16
收藏
得分:0 
自顶下
2013-09-26 12:46
holylightsj
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2013-8-16
收藏
得分:0 
谢谢楼上

求大神们帮忙
2013-09-27 13:21
holylightsj
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2013-8-16
收藏
得分:0 
回复 7楼 303770957
谢谢您啦!我再把您的代码好好研究下
2013-10-03 22:25
holylightsj
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2013-8-16
收藏
得分:0 
以下是引用303770957在2013-10-3 11:59:41的发言:

***********************************************************************
十一期间先来无事,有将你的问题重新实现了一下,思路可以看上面帖子的说明。
***********************************************************************
#include  //输出函数用到
#include  //读取文件用到
#include  //求绝对值的函数fabs
#define M 4      //M表示多项式的项数,可以根据拟合多项式的最高次数进行调整,M-1表示多项式的最高次数(这里最高次数为3,所以M为4。)
#define E 1e-15  //精度要求,可以自行调整。
using namespace std;
/***************************************************/
template
void IniArray(T *x,T *y,int count,T (&a)[C],T (&b)[C],T (&s)[C][C])
{
    for(int i=0; i
void Gaussian(const T Left[N][N], const T Right[N],T (&Result)[N])
{
    T Matrix[N][N+1];
    T t = 0;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N + 1; j++)
        {
            if (j == N)
            {
                Matrix[j] = Right;
            }
            else
            {
                Matrix[j] = Left[j];
            }
        }
    }
    for (int k = 0; k < N - 1; k++)
    {
        for (int i = k + 1; i < N; i++)
        {
            if (fabs(Matrix[k]) > fabs(Matrix[k][k]))
            {
                for (int j = k; j < N + 1; j++)
                {
                    t = Matrix[k][j];
                    Matrix[k][j] = Matrix[j];
                    Matrix[j] = t;
                }
            }
        }
        if (fabs(Matrix[k][ k]) < E)
        {
            return ;
        }
        for (int i = k + 1; i < N; i++)
        {
            Matrix[ k] = Matrix[k] / Matrix[k][k];
            for (int j = k + 1; j  
void DisplayInfo(T (&a)[C],T (&b)[C],T (&s)[C][C])
{
    cout<<"正规矩阵如下:"<
bool ReadDataFromTxt(string strFileName,int count,T *x,T *y)
{
    ifstream fin(strFileName.c_str());
    if (!fin)
    {
        cout<<"文件"<
您好 我尝试着在VC6.0上运行这段代码,出现了不少问题,请您帮我看下是什么原因谢谢啦
第一行从第一个include开始
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(9) : error C2265: '<Unknown>' : reference to a zero-sized array is illegal
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(9) : error C2265: '<Unknown>' : reference to a zero-sized array is illegal
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(9) : error C2265: '<Unknown>' : reference to a zero-sized array is illegal
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(9) : error C2087: '<Unknown>' : missing subscript
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(34) : error C2087: '<Unknown>' : missing subscript
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(34) : error C2265: '<Unknown>' : reference to a zero-sized array is illegal
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(96) : error C2265: '<Unknown>' : reference to a zero-sized array is illegal
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(96) : error C2265: '<Unknown>' : reference to a zero-sized array is illegal
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(96) : error C2265: '<Unknown>' : reference to a zero-sized array is illegal
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(96) : error C2087: '<Unknown>' : missing subscript
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(252) : error C2784: 'void __cdecl IniArray(T *,T *,int,T (&)[1],T (&)[1],T (&)[1][1])' : could not deduce template argument for ' (&)[1]' from 'double [4]'
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(255) : error C2784: 'void __cdecl Gaussian(const T [][1],const T [],T (&)[1])' : could not deduce template argument for 'const  [][1]' from 'double [4][4]'
C:\Documents and Settings\topoCFD\桌面\dongtai1\dongtai1.cpp(256) : error C2784: 'void __cdecl DisplayInfo(T (&)[1],T (&)[1],T (&)[1][1])' : could not deduce template argument for ' (&)[1]' from 'double [4]'
2013-10-05 12:50
holylightsj
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2013-8-16
收藏
得分:0 
以下是引用303770957在2013-9-29 01:11:45的发言:

闲的没事干,抽了点时间帮你实现了。

解题思路:求下列矩阵方程即可。
/******************************************************************************************************
11,                   x1+x2+...+x11,        x1^2+x2^2+...+x11^2,  x1^3+x2^3+...+x11^3   a0   y1+y2+...+y11
x1+x2+...+x11,        x1^2+x2^2+...+x11^2,  x1^3+x2^3+...+x11^3,  x1^4+x2^4+...+x11^4   a1   x1y1+x2y2+...+x11y11
x1^2+x2^2+...+x11^2,  x1^3+x2^3+...+x11^3,  x1^4+x2^4+...+x11^4,  x1^5+x2^5+...+x11^5   a2   x1^2y1+x2^2y2+...+x11^2y11
x1^3+x2^3+...+x11^3,  x1^4+x2^4+...+x11^4,  x1^5+x2^5+...+x11^5,  x1^6+x2^6+...+x11^6   a3   x1^3y1+x2^3y2+...+x11^3y11
*******************************************************************************************************/#include  //输出函数用到
#include  //读取文件用到
#include  //求绝对值的函数fabs
#define Count 11  //表示数据量
#define M 4       //M表示多项式的项数,M-1表示多项式的最高次数。
#define E 1e-15  //精度要求
using namespace std;
/***************************************************/
template
void IniArray(T (&x)[R],T (&y)[R],T (&a)[C],T (&b)[C],T (&s)[C][C]);
/**************************************************/
template
void Gaussian(const T Left[N][N], const T Right[N],T (&Result)[N]);
/***************************************************/
template
void DisplayInfo(T (&a)[C],T (&b)[C],T (&s)[C][C]);
/**************************************************/
template
void ReadDataFromTxt(T (&x)[C],T (&y)[C]);
//设拟合多项式为 P(x)=a0+a1x+a2x^2+a3x^3+...+am(x^m), 其中m为多项式的最高次数。
int main()
{
    float x[Count];//= {0,5,10,15,20,25,30,35,40,45,50};//Count为坐标的个数,x为横轴坐标值。
    float y[Count];//= {0,1.27,2.16,2.86,3.44,3.87,4.15,4.37,4.51,4.58,4.02};//y为纵轴坐标值。
    float s[M][M],a[M],b[M];//构造矩阵方程 s*a=b 求a
    ReadDataFromTxt(x,y);//读取拟合数据
    IniArray(x,y,a,b,s);//初始化数据
    Gaussian(s,b,a);//用高斯消去法求m维线性方程组s*a=b的解
    DisplayInfo(a,b,s);//显示计算结果数据信息
    return 0;
}
 
运行结果如下:
请输入采样数据文件名:shuru.txt
s[4][4]={
 {11,275,9625,378125},
 {275,9625,378125,1.58331e+07},
 {9625,378125,1.58331e+07,6.90078e+08},
 {378125,1.58331e+07,6.90078e+08,3.09126e+10}
}
b[4]={35.23,1101.35,40314.8,1.60787e+06}
由s*a=b => a=s(-1)*b 解得:
a[4]={0.0887425,0.233659,-0.00338393,6.79117e-06}
3次最小二乘拟合多项式为:
P(x)=0.0887425+0.233659x-0.00338393x^2+6.79117e-06x^3
还有这个EXE文件输入文件名后按回车就自动关闭了 是跟系统和版本什么的有关系吗?
2013-10-05 12:55
holylightsj
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2013-8-16
收藏
得分:0 
以下是引用303770957在2013-10-5 23:27:30的发言:


(1)我懒得去评价VC++ 6.0和Vs系列的编译器对标准C++的支持。
(2)我用的编译器是GNU GCC 编译器.
(3)你在VC++6.0下不能编译,现在我将exe文件贴给你吧。
注:不好意思,上一个exe运行之后闪一下就没有的原因是我没有让他暂停,所以你看不到结果的。
VC6.0确实很难用=。= 经常出些莫名其妙的错误
我去找个CODEBLOCK试试看
2013-10-06 22:25
holylightsj
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2013-8-16
收藏
得分:0 
以下是引用303770957在2013-10-6 23:50:33的发言:

嗯,是CodeBlocks我少弄了s上去。这个工具挺好的,是个快平台的,支持多种编译器,可以自己设置使用什么编译器来编译写好的程序,GCC对标准C++的支持达到了96%以上,C++的标准是在1999年诞生的,而vc6.0开发工具是在1998年诞生的,所以对标准C++的支持很差。现在很多人都再用GCC编译器来编译C++文件了,他对标准C++支持的很好。
我之前是用MFC做的拟合+绘制曲线,如果用codeblocks的话能搞MFC吗?
2013-10-08 13:09
快速回复:求大神帮我改改这个程序 设置可变动大小的数组(大概是关于动态内存分 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025196 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved