如何提高编程能力?(中)

17.求近似数

17.1 牛顿迭代法

如定积分、用牛顿迭代法或二分法或弦截法求多元方程的根

#include<stdio.h>
#include<math.h>
double func(double x)
{
    return x*x*x*x - 3 * x*x*x + 1.5*x*x - 4.0;
}
double func1(double x)
{
    return 4 * x*x*x - 9 * x*x + 3 * x;
}

int Newton(double *x,double precision,int maxcyc)
{
    double x1, x0;
    int k;
    x0 = *x;
    for (k = 0; k < maxcyc; k++)
    {
        if (func1(x0) == 0.0)
        {
            printf("迭代过程中导数为0!\n");
            return 0;
        }
        x1 = x0 - func(x0) / func1(x0);
        if (fabs(x1-x0) < precision || fabs(func(x1)) < precision)
        {
            *x = x1;
            return 1;
        }
        else
        {
            x0 = x1;
        }
    }
    printf("迭代次数超过预期!\n");
    return 0;
}

int main()
{
    double x, precision;
    int maxcyc;
    printf("输入初始迭代值x0:");
    scanf("%lf",&x);
    printf("输入最大迭代次数:");
    scanf("%d", &maxcyc);
    printf("迭代要求的精度:");
    scanf("%lf", &precision);
    if (Newton(&x, precision, maxcyc) == 1)
    {
        printf("该值附近的根为:%lf\n", x);
    }
    else
    {
        printf("迭代失败!\n");
    }
    return 0;
}

17.2 精简版

//精简版
#include<stdio.h>
#include<math.h>
double fun(double x)
{
    return 2*x*x*x - 4*x*x + 3*x - 6;
}
double fun1(double x)
{
    return 6*x*x - 8 * x + 3.0;
}

int main()
{
    double x, x0, f,f1,precision;
    printf("请输入初始x0:");
    scanf("%lf",&x);
    printf("请输入精度precision:");
    scanf("%lf",&precision);
    do
    {
        x0 = x;
        f=fun(x0);
    } while (fabs(x-x0)>= precision);
    printf("%lf\n",x);
    return 0;
}

17.3 二分法

  • 1 确定区间[a,b],验证f(a)·f(b)<0

  • 2 求区间(a,b)的中点x

  • 3 判断

  • 4 判断f(x)是否达到精确度ξ:即若┃f(c)┃<ξ,则x=c就是使f(x)接近零点的近似值,否则重复2-4.

#include&lt;stdio.h&gt;
#include&lt;math.h&gt;
int main()
{
    double func(double x);
    double root(double a, double b);
    root(-10,10);

    return 0;
}
double func(double x)
{
    return 2 * x*x*x - 4 * x*x + 3 * x - 6.0;
}

double root(double a, double b)
{
    double x;
    double a1=a, b1=b;
    x = (a + b) / 2;
    if(func(x)==0.0)
    {
        printf("该方程在%lf到%lf区间内的根为:%lf.\n",a1,b1,x);
        return x;
    }
    else
    {
        while (fabs(a - b) &gt; 1e-6)
        {
            if (func(a)*func(x) &lt; 0)
                b = x;
            else
                a = x;
            x = (a + b) / 2;
        }
    }
    printf("该方程在%lf到%lf区间内的根为:%lf.\n", a1, b1, x);
    return x;
}

17.4 弦截法

函数方程:x1-f1x2)/(f2-f1)

#include&lt;stdio.h&gt;
#include&lt;math.h&gt;
double xpoint(double x1, double x2);  //弦与x轴的交点横坐标
double root(double x1, double x2);    //求根函数
double f(double x); //求x点的函数值
int main()
{
    double x1, x2, f1, f2, x;

    do
    {
        printf("请输入x1,x2:");
        scanf("%lf,%lf",&amp;x1,&amp;x2);
        f1 = f(x1);
        f2 = f(x2);

    } while (f1*f2&gt;=0); //当循环运算到f(x1)*f(x2)&gt;=0时(0是必要条件参数),即f(x1)、f(x2)同符号,且任一个接近于0时,意味着与x轴接近相交,此时存在一个方程实根。
    x = root(x1,x2);
    printf("方程的一个解为:%.2f\n",x);
    return 0;
}

double xpoint(double x1, double x2)
{
    double x = 0;
    x = (x1*f(x2)-x2*f(x1)) / (f(x2)-f(x1));
    return x;
}
double root(double x1,double x2)
{
    double x, y, y1, y2;
    y1 = f(x1);
    y2 = f(x2);
    do
    {
        x = xpoint(x1,x2);
        y = f(x);
        if (y*y1 &gt; 0)
        {
            x1 = x;
            y1 = y;
        }
        else
        {
            x2 = x;
            y2 = y;
        }
    } while (fabs(y)&gt;=0.00001);

    return x;
}

double f(double x)
{
    double y = 0;
    y = x*x*x - 5 * x*x + 16 * x - 80;
    return y;
}

18.矩阵运算及二维数组

18.1 求两个矩阵之和、之积

#include&lt;stdio.h&gt;
#define N 2
int main()
{
    void print(int(*a)[N]);
    void vx(int(*a)[N], int(*b)[N]);
    int i, j;
    int a[N][N],b[N][N];
    printf("输入两个矩阵:\n");
    printf("矩阵1:\n");
    for (i = 0; i &lt; N; i++)
        for (j = 0; j &lt; N; j++)
            scanf("%d",&amp;a[i][j]);
    printf("---------\n");
    print(a);
    printf("矩阵2:\n");
    for (i = 0; i &lt; N; i++)
        for (j = 0; j &lt; N; j++)
            scanf("%d", &amp;b[i][j]);
    printf("---------\n");
    print(b);
    vx(a,b);
    return 0;
}
void vx(int (*a)[N],int (*b)[N])
{
    void print(int(*a)[N]);
    int i,j,k,res;
    int c[N][N],d[N][N];
    for (i = 0; i &lt; N; i++)
        for (j = 0; j &lt; N; j++)
        {
            res = 0;
            c[i][j] = a[i][j] + b[i][j];
            for(k=0;k&lt;N;k++)
                res += a[i][k] * b[k][j];
            d[i][j]=res;
        }
    printf("两矩阵相加:\n");
    print(c);
    printf("两矩阵相乘:\n");
    print(d);
}
void print(int (*a)[N])
{
    int i,j;
    for (i = 0; i &lt; N; i++)
    {
        for (j = 0; j &lt; N; j++)
            printf("%d ",a[i][j]);
        printf("\n");
    }
}

18.2 二维数组

二维数组某位置上的元素在该行上最大,该列上最小

#include&lt;stdio.h&gt;
int main()
{
    int a[4][5];
    int i, j, k, m;
    for (i = 0; i &lt; 4; i++)
        for (j = 0; j &lt; 5; j++)
            scanf("%d",&amp;a[i][j]);

    for (i = 0; i &lt; 4; i++)
    {
        for (j = 0; j &lt; 5; j++)
        {
            //扫描行,确定行中最大值
            for (k = 0; k &lt; 5; k++)
            {
                if (a[i][j] &lt; a[i][k])
                {
                    break;
                }
            }
            if (k == 5)
            {
                //扫描列,确定列中最小值
                for (m = 0; m &lt; 4; m++)
                {
                    if (a[i][j] &gt; a[m][j])
                        break;
                }
                if (m == 4)
                    printf("满足值:%d ",a[i][j]);
            }
        }
    }

    return 0;
}

19.位运算及应用

19.1 位运算

  • 1.与 &

  • 2.或 |

  • 3.非 ~

  • 4.异或

19.2 一个字节中被置为1的位的个数

#include&lt;stdio.h&gt;
int main()
{
    int sum = 0;
    //题中给出一个字节,则占8位,取值范围为0~255
    int a;
    printf("请输入一个字节的数,以十进制输入:\n");
    scanf("%d",&amp;a);
    if (a &lt; 0 || a&gt;255)
    {
        printf("error\n");
        return 1;
    }

    int i, k=1;
    for (i = 1; i &lt; 9; i++)
    {
        if (a == (a | k))
            sum++;
        k *= 2;
    }
    printf("共%d位\n",sum);
    return 0;
}

20.排序算法

20.1 快速排序

void sort(int *p, int low, int high)
{
    if (low &gt; high)
        return;

        int temp, i, j, t;
        temp = p[low];
        i = low;
        j = high;
        while (i &lt; j)
        {
            while (i&lt;j&amp;&amp;p[j]&gt;=temp)
                j--;
            while (i &lt; j&amp;&amp;p[i] &lt;= temp)
                i++;
            if (i &lt; j)
            {
                t = p[i];
                p[i] = p[j];
                p[j] = t;
            }
        }
        p[low] = p[i];
        p[i] = temp;
        sort(p,low,i-1);
        sort(p,i+1,high);
}

20.2 冒泡排序

void sort(int *p, int n)
{
    int i, j;
    int t;
    for (i = 0; i &lt; n - 1; i++)
    {
        for(j=0;j&lt;n-i-1;j++)
        {
            if (p[j] &gt; p[j + 1])
            {
                t = p[j];
                p[j] = p[j+1];
                p[j + 1] = t;
            }
        }
    }
}

20.3 选择排序

void sort(int *p, int n)
{
    int i, j, k, temp;
    for (i = 0; i &lt; n-1; i++)
    {
        k = i;
        for (j = i; j &lt; n; j++)
        {
            if (p[k] &gt; p[j])
                k = j;
        }

        temp = p[i];
        p[i] = p[k];
        p[k] = temp;
    }
}

20.4 直接插入排序

void sort(int *p, int n)
{
    int i,j,k,t;
    for(i=1;i&lt;n;i++)   //注意从第2个元素操作
    {
        if(p[i]&lt;p[i-1])
        {
            t=p[i];
            for(j=i-1;j&gt;=0&amp;&amp;p[j]&gt;t;j--)
            {
                p[j+1]=p[j];
            }
        }
        p[j+1]=t;
    }

}

//换成字符操作

void sort(char *p)
{
    int i,j,n;
    char ch;
    n=strlen(p);
    for(i=i;i&lt;n;i++)
    {
        ch=p[i];
        j=i-1;
        while((j&gt;=0)&amp;&amp;(ch&lt;p[j]))
        {
            p[j+1]=p[j];
            j--;
        }
        p[j+1]=ch;
    }
}

21.链表

21.1 单链表之增删改查

/*单链表*/
#include&lt;stdio.h&gt;
#include&lt;malloc.h&gt;
typedef struct Node {
    int data;
    struct Node *PNext;
}Node, *PNode;
#define ERROR 0
#define OK 1
PNode create_list()
{
    int len, i;
    printf("请输入链表的长度:len=\n");
    scanf("%d",&amp;len);
    PNode PHead = (PNode)malloc(sizeof(Node));
    PHead-&gt;PNext = NULL;
    PNode PTail=PHead;
    for (i = 0; i &lt; len; i++)
    {
        int val;
        printf("请输入第%d个元素的值:",i+1);
        scanf("%d",&amp;val);
        PNode PNew = (PNode)malloc(sizeof(Node));
        PNew-&gt;data = val;
        PNew-&gt;PNext = NULL;
        PTail-&gt;PNext=PNew;
        PTail = PNew;
    }
    return PHead;

}


void outLink(PNode pHead)
{
    PNode p = pHead-&gt;PNext;
    while (p)
    {
        printf("%d ",p-&gt;data);
        p = p-&gt;PNext;
    }
    putchar('\n');
}

PNode reverse(PNode pHead)
{
    PNode p = pHead-&gt;PNext;

    PNode q,r;
    q = p-&gt;PNext;
    p-&gt;PNext = NULL;
    while (q)
    {
        r = p;
        p = q;
        q = p-&gt;PNext;
        p-&gt;PNext = r;
    }
    pHead-&gt;PNext = p;

    return pHead;
}

int list_num(PNode pHead)
{
    int num = 0;
    PNode p = pHead-&gt;PNext;
    while (p)
    {
        num++;
        p = p-&gt;PNext;
    }
    return num;
}


//pos从1开始
/*
    12345
    有6个插入位置
*/
int insert_list(pnode phead, int val, int pos)
{
    int i;

    pnode p = phead-&gt;pnext;
    int length = list_num(p);
    if (pos&lt;1 || pos&gt;length+2)
        return error;
    else
    {
        i = 0;

        //定位到pos前一位,在下标pos-1处插入结点,需要知道前一结点
        while (p&amp;&amp;i &lt; pos - 2)
        {
            i++;
            p = p-&gt;pnext;
        }
        if (p||(i == pos - 2))
        {
            pnode pnew = (pnode)malloc(sizeof(pnode));
            pnew-&gt;data = val;
            if (pos == 1)
            {
                pnew-&gt;pnext = p;
                phead-&gt;pnext = pnew;
            }
            else if (pos == length+2)
            {
                p-&gt;pnext = pnew;
                pnew-&gt;pnext=null;
            }
            else
            {

                pnew-&gt;pnext = p-&gt;pnext;
                p-&gt;pnext = pnew;
            }
            length++;
            return ok;
        }
        else
            return error;
    }
}

int insert_list(PNode pHead, int val, int pos)
{

    PNode p = pHead;
    int length = list_num(p),i;
    if (pos&lt;0 || pos&gt;length ||!p)
        return ERROR;
    else
    {
        i = -1;
        while (p&amp;&amp;i &lt; pos - 1)
        {
            i++;
            p=p-&gt;PNext;
        }
        if (i == pos - 1 || p)
        {
            PNode PNew = (PNode)malloc(sizeof(PNode));
            PNew-&gt;data = val;
            if (i == -1)
            {
                PNew-&gt;PNext = pHead-&gt;PNext;
                pHead-&gt;PNext = PNew;
            }
            else if (pos == length)
            {
                p-&gt;PNext = PNew;
                PNew-&gt;PNext = NULL;
            }
            else
            {
                PNew-&gt;PNext = p-&gt;PNext;
                p-&gt;PNext = PNew;
            }
            length++;
            return OK;
        }
        else
            return ERROR;
    }
}
//删除,根据结点值删除
int delData(PNode pHead, int *val)
{
    int length = list_num(pHead);
    PNode p = pHead,q;

    if (!p)
        return ERROR;
    while (p-&gt;PNext!=NULL)
    {
        if (p-&gt;PNext-&gt;data == *val)
        {
            q = p-&gt;PNext;
            p-&gt;PNext = p-&gt;PNext-&gt;PNext;
            free(q);
        }
        else
            p = p-&gt;PNext;
    }

    return OK;
}

//删除,按照位置删除,且pos从1开始

int delpos(PNode pHead, int pos)
{
    PNode q = pHead;
    PNode p = q-&gt;PNext;
    int length = list_num(pHead);
    if (pos&lt;1 || pos&gt;length)
        return ERROR;
    else
    {
        int i = 1;
        while (i &lt; pos - 1)
        {
            i++;
            q = p;
            p = p-&gt;PNext;
        }
        if (pos == 1)
            pHead-&gt;PNext = pHead-&gt;PNext-&gt;PNext;
        else if (pos == length)
            q-&gt;PNext = NULL;

        length--;

        return OK;
    }
}

//或者pos从0开始计算
/*12345
有0~length范围可插入
*/
int main()
{
    int num;
    PNode PHead = create_list();
    outLink(PHead);

    num = list_num(PHead);
    putchar('\n');
    printf("共有%d个结点.\n", num);
    PNode rp = reverse(PHead);
    outLink(rp);
    int val;
    printf("请输入插入结点的值:");
    scanf("%d", &amp;val);
    int pos;
    printf("请输入插入结点的位置(从1开始):");
    scanf("%d", &amp;pos);
    int flag = insert_list(rp, val, pos);
    if (flag == 1)
    {
        printf("插入结点成功,共%d个结点\n", list_num(rp));
        outLink(rp);
    }
    else
        printf("插入失败.\n");

    int data;
    printf("请输入要删除的结点值:");
    scanf("%d", &amp;data);
    int f = delData(rp, &amp;data);
    if (f == 1)
    {
        printf("删除%d成功!\n", data);
        outLink(rp);
    }
    else
        printf("删除结点不存在!\n");
    int delposi;
    printf("请输入要删除的位置:");
    scanf("%d", &amp;delposi);
    int f1 = delpos(rp, delposi);
    if (f1 == 1)
    {
        printf("删除第%d个位置成功!\n", delposi);
        outLink(rp);
    }
    else
        printf("删除位置不存在!\n");
}

21.2 头插法

头插法思路:先判断是否为head结点,若为head结点,则将新造的结点先赋值,然后链接在head后面,并将此时结点的next设为空,因为此时表示末尾结点,否则会出错!!!

node * createlist()
{
    int n;
    node *head = (node *)malloc(sizeof(node));
    node *p = head;
    head-&gt;next = NULL;
    if (head == NULL)
    {
        printf("申请空间失败!\n");
        return NULL;
    }
    else
    {
        printf("请输入结点个数,n=");
        scanf("%d",&amp;n);
        int i,num;
        for (i = 0; i &lt; n; i++)
        {
            printf("请输入第%d个结点数值:\n",i+1);
            scanf("%d",&amp;num);
            node *q = (node *)malloc(sizeof(node));
            if (p == head)
            {
                head-&gt;next = q;
                q-&gt;data = num;
                q-&gt;next = NULL;
            }
            else
            {
                q-&gt;data = num;
                q-&gt;next = p;

            }
            p = q;

        }
        head-&gt;next = p;

    }

    return head;
}

21.3 链表逆置

NODE *reverseList(NODE *h)
{
    NODE *p, *q, *r;
    p = h;
    if (!p)
        return NULL;
    q = p-&gt;next;
    p-&gt;next = NULL;
    while (q)
    {
        r = q-&gt;next;
        q-&gt;next = p;
        p = q;
        q = r
    return p;
}

640?wx_fmt=png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 目的: (1)通过采用牛顿迭代法、弦截法和二分法求根的程序设计,使学生更加系统地理解和掌握C语言函数间参数传递方法、数组和指针的应用等编程技巧。培养学生综合利用C语言进行科学计算,使学生将所学知识转化为分析和设计数学的实际问题的能力,学会查资料和工具书。 (2)提高学生建立程序文档、归纳总结的能力。 (3)进一步巩固和灵活运用先修课程《计算机文化基础》有关文字处理、图表分析、数据归整、应用软件之间图表、数据共享等信息技术处理的综合能力。 2. 基本要求: (1)要求用模块化设计和C语言的思想来完成程序的设计; (2)要求分别编写牛顿迭代法、弦截法和二分法求根的函数,分别存到不同的.CPP文件; (3)在VC++6.0环境,学会调试程序的方法,及时查究错误,独立调试完成。 (4)程序调试通过后,完成程序文档的整理,加必要的注释。 一般解一元方程,常用采用的方法有:牛顿迭代法、弦截法和二分法等。 牛顿迭代法求根 〖〖f(x)=a〗_0 x〗^n 〖〖 + a〗_1 x〗^(n-1) +⋯+〖 a〗_(n-2) x^2 +〖 a〗_(n-1) x +〖 a〗_n=0 求f(x)在〖 x〗_0附近的根。 计算公式:〖 x〗_(n+1)=〖 x〗_n- f(〖 x〗_n )/(f(〖 x〗_n)) ́ 精度:ε=|〖 x〗_(n+1)-〖 x〗_n|<1.0e-m ,m=6。 牛顿迭代法 所求的根:满足精度的〖 x〗_n 二分法 任取两点〖 x〗_1和〖 x〗_2,判断(〖 x〗_1, 〖 x〗_2)有无实根。如下图所示,如果f(〖 x〗_1 )和f(〖 x〗_2 )符号相反,说明(〖 x〗_1, 〖 x〗_2)之间有一实根。取(〖 x〗_1, 〖 x〗_2)的点x,检查f(x)和f(〖 x〗_1 )是否同符号,如果不同号,说明实根在(〖 x〗_1,x)区间,x作为新的〖 x〗_2,舍弃(x, 〖 x〗_2)区间;若同号,则实根在(x, 〖 x〗_2)区间,x作为新的〖 x〗_1, 舍弃(〖 x〗_1,x)区间。再根据新的〖 x〗_1 、 〖 x〗_2,找点,重复上述步骤。直到|〖 x〗_1-〖 x〗_2|〖<10〗^(-6)时,x =(〖 x〗_1+〖 x〗_2)/2为所求。 (3)弦截法 取f(〖 x〗_1 )与f(〖 x〗_2 )连线与x轴的交点x,从(〖 x〗_1, x)和(x, 〖 x〗_2)两个区间取舍的方法与二分法相同。 计算公式为: 判断f(〖 x〗_1 )与f(〖 x〗_2 )是否同符号的方法与二分法采用的方法相同。直到先后两次求出的x的值之差小于〖10〗^(-6)为止。 分别用牛顿迭代法、弦截法和二分法求下列方程的根,分析比较各种方法的迭代次数及精度。 〖f(x)=x〗^3 〖- 2x〗^2 +7x +4=0 牛顿迭代法的初值:x=0.5; 弦截法〖 x〗_1,〖 x〗_2的初值:-1,1 二分法〖 x〗_1,〖 x〗_2的初值:-1,0 精度要求:|〖 x〗_1-〖 x〗_2| 〖<10〗^(-6)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值