前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何提高编程能力?(中)

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

作者头像
公众号guangcity
发布2019-09-20 14:34:30
8000
发布2019-09-20 14:34:30
举报
文章被收录于专栏:光城(guangcity)光城(guangcity)

17.求近似数

17.1 牛顿迭代法

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

代码语言:javascript
复制
#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 精简版

代码语言:javascript
复制
//精简版
#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 判断 (1) 若f(a)·f(c)<0,则令b=x; (2) 若f(x)·f(b)<0,则令a=x.
  • 4 判断f(x)是否达到精确度ξ:即若┃f(c)┃<ξ,则x=c就是使f(x)接近零点的近似值,否则重复2-4.
代码语言:javascript
复制
#include<stdio.h>
#include<math.h>
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) > 1e-6)
        {
            if (func(a)*func(x) < 0)
                b = x;
            else
                a = x;
            x = (a + b) / 2;
        }
    }
    printf("该方程在%lf到%lf区间内的根为:%lf.\n", a1, b1, x);
    return x;
}

17.4 弦截法

函数方程: y - f2 = (f2 - f1) / (x2 - x1)(x - x2) 化简得: x=(f2x1-f1x2)/(f2-f1)

代码语言:javascript
复制
#include<stdio.h>
#include<math.h>
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",&x1,&x2);
        f1 = f(x1);
        f2 = f(x2);

    } while (f1*f2>=0); //当循环运算到f(x1)*f(x2)>=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 > 0)
        {
            x1 = x;
            y1 = y;
        }
        else
        {
            x2 = x;
            y2 = y;
        }
    } while (fabs(y)>=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 求两个矩阵之和、之积

代码语言:javascript
复制
#include<stdio.h>
#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 < N; i++)
        for (j = 0; j < N; j++)
            scanf("%d",&a[i][j]);
    printf("---------\n");
    print(a);
    printf("矩阵2:\n");
    for (i = 0; i < N; i++)
        for (j = 0; j < N; j++)
            scanf("%d", &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 < N; i++)
        for (j = 0; j < N; j++)
        {
            res = 0;
            c[i][j] = a[i][j] + b[i][j];
            for(k=0;k<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 < N; i++)
    {
        for (j = 0; j < N; j++)
            printf("%d ",a[i][j]);
        printf("\n");
    }
}

18.2 二维数组

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

代码语言:javascript
复制
#include<stdio.h>
int main()
{
    int a[4][5];
    int i, j, k, m;
    for (i = 0; i < 4; i++)
        for (j = 0; j < 5; j++)
            scanf("%d",&a[i][j]);

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

    return 0;
}

19.位运算及应用

19.1 位运算

  • 1.与 & 1&0=0;0&0=0;1&1=1;
  • 2.或 | 1|0=1;0|0=0;1|1=1;
  • 3.非 ~ ~1=-2 ~16=-17 00010000 16二进制数 11101111 16二进制数取非运算 取反+1即: 00010000+1=00010001=-17
  • 4.异或 1^0=1;0^0=0;1^1=0

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

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

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

20.排序算法

20.1 快速排序

代码语言:javascript
复制
void sort(int *p, int low, int high)
{
    if (low > high)
        return;

        int temp, i, j, t;
        temp = p[low];
        i = low;
        j = high;
        while (i < j)
        {
            while (i<j&&p[j]>=temp)
                j--;
            while (i < j&&p[i] <= temp)
                i++;
            if (i < 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 冒泡排序

代码语言:javascript
复制
void sort(int *p, int n)
{
    int i, j;
    int t;
    for (i = 0; i < n - 1; i++)
    {
        for(j=0;j<n-i-1;j++)
        {
            if (p[j] > p[j + 1])
            {
                t = p[j];
                p[j] = p[j+1];
                p[j + 1] = t;
            }
        }
    }
}

20.3 选择排序

代码语言:javascript
复制
void sort(int *p, int n)
{
    int i, j, k, temp;
    for (i = 0; i < n-1; i++)
    {
        k = i;
        for (j = i; j < n; j++)
        {
            if (p[k] > p[j])
                k = j;
        }

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

20.4 直接插入排序

代码语言:javascript
复制
void sort(int *p, int n)
{
    int i,j,k,t;
    for(i=1;i<n;i++)   //注意从第2个元素操作
    {
        if(p[i]<p[i-1])
        {
            t=p[i];
            for(j=i-1;j>=0&&p[j]>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<n;i++)
    {
        ch=p[i];
        j=i-1;
        while((j>=0)&&(ch<p[j]))
        {
            p[j+1]=p[j];
            j--;
        }
        p[j+1]=ch;
    }
}

21.链表

21.1 单链表之增删改查

代码语言:javascript
复制
/*单链表*/
#include<stdio.h>
#include<malloc.h>
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",&len);
    PNode PHead = (PNode)malloc(sizeof(Node));
    PHead->PNext = NULL;
    PNode PTail=PHead;
    for (i = 0; i < len; i++)
    {
        int val;
        printf("请输入第%d个元素的值:",i+1);
        scanf("%d",&val);
        PNode PNew = (PNode)malloc(sizeof(Node));
        PNew->data = val;
        PNew->PNext = NULL;
        PTail->PNext=PNew;
        PTail = PNew;
    }
    return PHead;

}


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

PNode reverse(PNode pHead)
{
    PNode p = pHead->PNext;

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

    return pHead;
}

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


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

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

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

                pnew->pnext = p->pnext;
                p->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<0 || pos>length ||!p)
        return ERROR;
    else
    {
        i = -1;
        while (p&&i < pos - 1)
        {
            i++;
            p=p->PNext;
        }
        if (i == pos - 1 || p)
        {
            PNode PNew = (PNode)malloc(sizeof(PNode));
            PNew->data = val;
            if (i == -1)
            {
                PNew->PNext = pHead->PNext;
                pHead->PNext = PNew;
            }
            else if (pos == length)
            {
                p->PNext = PNew;
                PNew->PNext = NULL;
            }
            else
            {
                PNew->PNext = p->PNext;
                p->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->PNext!=NULL)
    {
        if (p->PNext->data == *val)
        {
            q = p->PNext;
            p->PNext = p->PNext->PNext;
            free(q);
        }
        else
            p = p->PNext;
    }

    return OK;
}

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

int delpos(PNode pHead, int pos)
{
    PNode q = pHead;
    PNode p = q->PNext;
    int length = list_num(pHead);
    if (pos<1 || pos>length)
        return ERROR;
    else
    {
        int i = 1;
        while (i < pos - 1)
        {
            i++;
            q = p;
            p = p->PNext;
        }
        if (pos == 1)
            pHead->PNext = pHead->PNext->PNext;
        else if (pos == length)
            q->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", &val);
    int pos;
    printf("请输入插入结点的位置(从1开始):");
    scanf("%d", &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", &data);
    int f = delData(rp, &data);
    if (f == 1)
    {
        printf("删除%d成功!\n", data);
        outLink(rp);
    }
    else
        printf("删除结点不存在!\n");
    int delposi;
    printf("请输入要删除的位置:");
    scanf("%d", &delposi);
    int f1 = delpos(rp, delposi);
    if (f1 == 1)
    {
        printf("删除第%d个位置成功!\n", delposi);
        outLink(rp);
    }
    else
        printf("删除位置不存在!\n");
}

21.2 头插法

头插法思路:先判断是否为head结点,若为head结点,则将新造的结点先赋值,然后链接在head后面,并将此时结点的next设为空,因为此时表示末尾结点,否则会出错!!! 此次结束后,将p指向q所指的结点,然后新造结点将q结点的next链接到p,在往前,最后用将p结点链接至head结点后面即可!

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

            }
            p = q;

        }
        head->next = p;

    }

    return head;
}

21.3 链表逆置

代码语言:javascript
复制
NODE *reverseList(NODE *h)
{
    NODE *p, *q, *r;
    p = h;
    if (!p)
        return NULL;
    q = p->next;
    p->next = NULL;
    while (q)
    {
        r = q->next;
        q->next = p;
        p = q;
        q = r
    return p;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-12-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 17.求近似数
    • 17.1 牛顿迭代法
      • 17.2 精简版
        • 17.3 二分法
          • 17.4 弦截法
          • 18.矩阵运算及二维数组
            • 18.1 求两个矩阵之和、之积
              • 18.2 二维数组
              • 19.位运算及应用
                • 19.1 位运算
                  • 19.2 一个字节中被置为1的位的个数
                  • 20.排序算法
                    • 20.1 快速排序
                      • 20.2 冒泡排序
                        • 20.3 选择排序
                          • 20.4 直接插入排序
                          • 21.链表
                            • 21.1 单链表之增删改查
                              • 21.2 头插法
                                • 21.3 链表逆置
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档