CTDL: tìm lỗi logic.

Thảo luận trong 'Thuật toán' bắt đầu bởi integer, 3 Tháng mười 2010.

  1. Offline

    integer

    • Tiếu Ngạo Giang Hồ

    • :-?
    Số bài viết:
    1.695
    Đã được thích:
    1.313
    Điểm thành tích:
    900
    bài dưới đây là 1 lỗi thường gặp khi các bạn làm bt CTDL. các bạn xem tại sao không xóa được các số nhỏ hơn 10 ?. cùng thảo luận và rút kinh nghiệm.:001:
    Mã:
    /*##### LT03C - VietHanIT ######*/
    #include<stdio.h>
    #define max 20
    typedef struct{
        int ds[max];
        int ptcuoi;
    }danhsach;
    
    int kiemtra(danhsach D,int x)
    {
        for(int i=0;i<D.ptcuoi;)
        {
            if(D.ds[i]==x)
                return i;
            else
                i++;
        }
        return -1;
    }
    //xoa 1 so
    void xoa(danhsach &D,int x)
    {
        int i;
        for(i=0;i<D.ptcuoi;i++)
            if(D.ds[i]==x)
            {
                for(int j=i;j<=D.ptcuoi;j++)
                D.ds[j]=D.ds[j+1];
            }D.ptcuoi--;
    }
    //chen
    void chen(danhsach &D,int so,int vt)
    {
        int i;
        for(i=D.ptcuoi;i>=vt;i--)
        {
            D.ds[i+1]=D.ds[i];
        }
        D.ptcuoi++;
        D.ds[vt]=so;
    
    }
    //tim min
    int min(danhsach D)
    {
        int min=D.ds[0];
        for(int i=0;i<D.ptcuoi;i++)
            if(D.ds[i]<min)
                min=D.ds[i];
        return min;
    }
    int daytang(danhsach D)
    {
            for(int i=0;i<D.ptcuoi;)
            if(D.ds[i]>D.ds[i+1])
            return 1;
            else
            i++;
            return 0;
    }
    
    void inds(danhsach D)
    {
        for(int i=0;i<D.ptcuoi;i++)
        printf("%d ",D.ds[i]);
        printf("\n");
    }
    main()
    {
        int i,int_n,int_x;
        danhsach D;
        //tao ds
        D.ptcuoi=0;
        //nhap ds
        printf("\nNhap so phan tu ds: ");
        scanf("%d",&int_n);
        for(i=0;i<int_n;i++)
            {
                printf("\nNhap %d: ",i+1);
                scanf("%d",&D.ds[i]);
                D.ptcuoi++;
            }
        inds(D);
        //kiem tra tang giam cua day
        if(daytang(D)==1)
            printf("\nDay khong tang!");
        else
            printf("\nDay tang!");
        //min
        printf("\nPhan tu nho nhat: %d",min(D));
    
        //nhap so nguyen x, kiem tra co thuoc day hay khong
        printf("\nNhap X: ");
        scanf("%d",&int_x);
        if(kiemtra(D,int_x)==-1)
            printf("\nX Khong thuoc day!");
        else
            printf("\nvi tri cua x: %d ",kiemtra(D,int_x)+1);
    
    
        //xoa
        int int_xoa,int_vt;
        printf("\nNhap so can xoa: ");
        scanf("%d",&int_xoa);
            if(kiemtra(D,int_xoa)==-1)
                printf("\n\aVi tri khong hop le!\n");
            else
                xoa(D,int_xoa);
        inds(D);
    
        //chen so vao vi tri
        int int_chen,int_vtchen;
    
        printf("\nNhap so can chen: ");
        scanf("%d",&int_chen);
        printf("\nVi tri can chen: ");
        scanf("%d",&int_vtchen);
        int_vtchen-=1;
        chen(D,int_chen,int_vtchen);
        inds(D);
        //xoa so nho hon 10
        printf("\nXoa cac so nho hon 10\n");
        for(i=0;i<D.ptcuoi;i++)
            {
                for(int j=i;j<=D.ptcuoi;j++)
                if(D.ds[j]<10)
                xoa(D,D.ds[j]);
            }
        inds(D);
    
    }
    
    
  2. Offline

    hoekaka

    • Windows 95

    Số bài viết:
    359
    Đã được thích:
    114
    Điểm thành tích:
    90
    mắc lỗi này có lẽ là nhiều bạn dùng hàm for .. mà biến i của hàm for khi xóa sẽ khác vs vị trí các phần tử (khi xóa thì vị trí các pt trong ds sẽ bị thay đổi) còn biến i trong for thì ko ..

    mình hiểu thế .. viết ra chắc hơi khó hiểu :D
    integer thích bài này.
  3. Offline

    integer

    • Tiếu Ngạo Giang Hồ

    • :-?
    Số bài viết:
    1.695
    Đã được thích:
    1.313
    Điểm thành tích:
    900
    mình cũng nghĩ thế, hàm xóa dùng để xóa giá trị. còn khi xóa các số nhỏ hơn 10 ta lại truyền cho nó vị trí.
    bạn để ý cái này không:
    Mã:
        //xoa
        int int_xoa,int_vt;
        printf("\nNhap so can xoa: ");
        scanf("%d",&int_xoa);
            if(kiemtra(D,int_xoa)==-1)
                printf("\n\aVi tri khong hop le!\n");
            else
                xoa(D,int_xoa);
        inds(D);
    
  4. Offline

    LieuKyThien

    • Thành Viên Mới

    Số bài viết:
    79
    Đã được thích:
    49
    Điểm thành tích:
    0
    Hơ! nếu thảo luận về cách xóa những phần tử <= x thì nên post đoạn mã xử lý thôi chứ làm nguyên sơ ri thế này đọc mỏi mắt quá. Góp ý nè:
    for(i=0;i<n;)
    {
    if(a<x)
    xóa;
    else
    i++;
    }
    Nếu xóa thì không tăng i còn không xóa thì tăng lên để duyệt phần tử tiếp theo
    sunboy thích bài này.
  5. Offline

    TruTra

    • Friends

    • Oi vua giong face, vua giong yahoo= mang xha roi :D
    Số bài viết:
    499
    Đã được thích:
    200
    Điểm thành tích:
    140
    Đơn giản là thế này
    for(i=0;i<D.ptcuoi;i++)
    if(D.ds==x)
    {
    for(int j=i;j<=D.ptcuoi;j++)
    D.ds[j]=D.ds[j+1];
    }D.ptcuoi--;
    Ở đây 1 lần gọi hàm là một lần
    D.ptcuoi--;
    Vì thế chỉ xóa được một lần thoai.
    Xem lai dễ...
    Còn việc đặt thêm vòng lặp j=i là hoàn toàn phung phí.
    Cái này có thể rút gọn lại cho i và i+1
  6. Offline

    integer

    • Tiếu Ngạo Giang Hồ

    • :-?
    Số bài viết:
    1.695
    Đã được thích:
    1.313
    Điểm thành tích:
    900

    uhm, chỗ này thừa 1 chút, ban đầu lấy ra từ thuật toán sắp xếp, mình quên đổi lại.
    ai biết disasm ra như thế nào không.

Chia sẻ trang này

Advertising: Linux system admin | nukeviet | nukeviet 4 | Upload ảnh miễn phí