1. 程式人生 > >#Cprove20~21查詢與排序

#Cprove20~21查詢與排序

NO.1 簡單氣泡排序

對比下標從0開始與從1開始的區別。 在這裡插入圖片描述

NO.2 二分法解方程

對於區間[a,b]上連續不斷且f(a)·f(b)<0的函式y=f(x),通過不斷地把函式f(x)的零點所在的區間一分為二,使區間的兩個端點逐步逼近零點,進而得到零點近似值的方法叫二分法。 假設要求方程f(x)=0的解,給定精確度ξ。其演算法是:

  1. 確定區間[a,b],驗證f(a)·f(b)<0
  2. 求區間(a,b)的中點c
  3. 判斷 (1) 若f(a)·f(c)<0,則令b=c; (2) 若f(c)·f(b)<0,則令a=c.
  4. 判斷f(c)是否達到精確度ξ:即若┃f(c)┃<ξ,則x=c就是使f(x)接近零點的近似值,否則重複2-4.

請按照上面的演算法,程式設計序求解方程f(x)=2x^3-5x^2+3x-6=0,要求精確到0.00001.

#include <stdio.h>
#include<math.h>
double f(double x);
int main( )
{
    double a0,a,b0,b,c;    //定義區間[a0,b0],中點c
    do
    {
        printf("輸入求根區間:");
        scanf("%lf %lf",&a0,&b0);
    }
    while(f(a0)*f(b0)>=0);    //保證函式值在[a0,b0]上異號
a=a0; b=b0; c=(a+b)/2; while(fabs(f(c))>1e-5) { if(f(c)*f(a)<0) b=c; //f(a),f(c)異號,把c給b else a=c; c=(a+b)/2; } printf("區間[%.2lf,%.2lf]根為:%.5lf",a0,b0,c); return 0; } double f(double x) { double fx; fx=2
*x*x*x-5*x*x+3*x-6; return fx; }

執行結果 在這裡插入圖片描述

NO.3 有序陣列中插入資料

定義好一個有10個元素的陣列,先輸入9個呈升序的數作為前9個元素,再輸入一個數,要求按原來排序的規律將它插入陣列中。 例如,9個呈升序的數為1 7 8 17 23 24 59 62 101,需要插入的數字為50,輸出的序列則為1 7 8 17 23 24 50 59 62 101。

#include <stdio.h>
#define SIZE 5
int main( )
{
    int i,t,j,n,a[SIZE]= {0};
    printf("Input SIZE-1 num: ");
    i=0;
    do          //對 SIZE-1 個數輸入並排序
    {
        scanf("%d",&a[i]);
        if(a[i+1]>a[i])
        {
            t=a[i];
            a[i]=a[i+1];
            a[i+1]=t;
        }
        i++;
    }
    while(i<SIZE-1);
    printf("Input n : ");
    scanf("%d",&n);
    if(n<a[0])          //輸入數n小於序列最小數則放a[0]
        {
            for(j=SIZE-1; j>0; j--)
                a[j]=a[j-1];
            a[0]=n;
            for(i=0; i<SIZE; i++)
                printf("%d ",a[i]);
            return 0;
        }
    else if(n>a[SIZE-2])    //輸入數n大於序列最大數則放a[SIZE-1]
        {
            a[SIZE-1]=n;
            for(i=0; i<SIZE; i++)
                printf("%d ",a[i]);
            return 0;
        }
    for(i=0; i<SIZE-1; i++) //輸入數n在序列範圍內則插入到a[i+1]位置
    {
        if(n>=a[i]&&n<=a[i+1])
        {
            for(j=SIZE-1; j>i; j--)
                a[j]=a[j-1];
            a[i+1]=n;
            for(i=0; i<SIZE; i++)
                printf("%d ",a[i]);
            break;
        }
    }
    return 0;
}

執行結果 在這裡插入圖片描述

NO.4 工資的排序

從檔案salary.txt中讀入工人的工資(不超過500人),全部增加20%(好事),然後對工資資料進行排序,將排序後的結果儲存到檔案ordered_salary.txt中。

#include <stdio.h>
#include<stdlib.h>
int main( )
{
    int n=0;
    double sala[500]= {0};
    FILE *fp,*fp1;

    if((fp=fopen("salary.txt","r"))==NULL)
    {
        printf("Can not open!\n");
        exit(1);
    }
    if((fp1=fopen("ordered_salary.txt","w"))==NULL)
    {
        printf("Can not open!\n");
        exit(1);
    }
    n=0;
    while((fscanf(fp,"%lf",&sala[n]))!=EOF) //讀取資料放到sala[]
    {
        sala[n]=sala[n]*1.2;
        n++;
    }       //迴圈完畢sala[n]==EOF(除錯看到為零1.79e-307),說明只讀取到n個數(sala[0]開始)
    fclose(fp);

    int i,j;
    double t;
    for(i=0; i<n-1; i++)
        for(j=0; j<n-i-1; j++)
        {
            if(sala[j]>sala[j+1])
            {
                t=sala[j];
                sala[j]=sala[j+1];
                sala[j+1]=t;
            }
        }
    for(i=0;i<n;i++)    //n個數據寫入ordered_salary.txt
        fprintf(fp1,"%.2lf\n",sala[i]);
    fclose(fp1);
    return 0;
}

執行結果 在這裡插入圖片描述

小結

易錯點:

  1. 檔案指標錯定義為int型
  2. 直接在原檔案操作排序。用一個二元素陣列a[2]直接循序漸進讀取檔案資料並排序,只遍歷一次,而沒有采取把資料寫入到500元素陣列,對陣列元素氣泡排序
  3. 對檔案操作不熟悉