Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Trang 1 của 2 12 CuốiCuối
Kết quả 1 đến 10 của 14
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Hỏi về một bài liên quan đến mảng 1 chiều

    Chào mọi người,

    Mình có gặp 1 bài có yêu cầu như sau:

    Xây dựng hàm “void printArray(int a[10], int n)” in ra dãy a sau khi thực hiện yêu cầu sau.
    Xóa các phần tử có giá trị bằng n và dời dãy sang trái, thế giá trị 0 vào các phần tử trống
    ở cuối dãy.
    Ví dụ:
    printArray({1, 2, 2, 3, 4, 5, 6, 7, 8, 9}, 2) → 1, 3, 4, 5, 6, 7, 8, 9, 0, 0

    Đây là code của mình
    Mình nói luôn vấn đề. Code mình chạy ok nếu trong dãy ko có 2 số nào cần xóa mà lại đứng sát nhau. Nếu có 2 số đứng sát nhau là bị lỗi. Mình đã thử khác nhiều cách mà chưa tìm ra cách nào để xử lí cả. Mọi người xem thử nhé.


    Mã:
    #include <iostream>
    using namespace std;
    void printArray(int a[10], int n){
    	int i = 0, dem = 0, tam,j, d2=0,k;
    	for (i = 0; i < 10; i++){
    		if (a[i] == n){
    			for (j = i; j<10; j++){
    				tam = a[j];
    				a[j] = a[j + 1];
    				a[j + 1] = tam;
    			}
    			d2++;
    		}
    	}
    	for (i = 9; i>(9 - d2+1); i--)  
    		a[i] = 0;
    	for (i = 0; i < 10; i++)
    		cout << a[i] << "  ";
    }
    int main(){
    	int a[10], n;
    	cout << "Chuan bi nhap vao mot mang:" << endl;
    	for (int i = 0; i < 10; i++){
    		cout << "Nhap vao phan tu thu " << i << ": ";
    		cin >> a[i];
    		cout << endl;
    	}
    	cout << "Nhap vao mot gia tri: ";
    	cin >> n;
    	printArray(a,n);
    	cin >> n;
    	return 0;
    }

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    - Bạn phải giữ size cũ.
    - Việc xóa như yêu cầu là O(n), chủ yếu là bạn đã xóa mấy số rồi.

  3. #3
    Trích dẫn Gửi bởi prog10
    - Bạn phải giữ size cũ.
    - Việc xóa như yêu cầu là O(n), chủ yếu là bạn đã xóa mấy số rồi.
    Mình ko xóa bạn ơi. Mình ví dụ cho dễ hiểu.

    Ví dụ mình có dãy

    1 5 4 8 7 9 5 6 3 2 1 và n=5

    thì code cũng mình sẽ thực hiện như sau:

    cho dãy về dạng: 1 4 8 7 9 6 3 2 1 5 5

    Sau đó, có 2 số 5 thì cho 2 số cuối cùng trong dãy là 0.

    Trường hợp thế thì OK.

    Còn trường hợp 1 2 2 4 6 9 5 4 7 5 2

    thì khi chạy sẽ còn 1 số 2 ở đầu. Vì khi trong thuật toán của mình là nếu gặp số trong dãy trùng với số nhập vào, thì đổi chỗ nó cho đến khi nó về cuối thì thôi. Như vậy cả dãy bên phải sẽ không bị chuyển đổi. Nhưng ngặt nỗi nếu có 2 số trùng nhau thì sẽ có một số bị bỏ qua do i nó vẫn cứ chạy.

    Bạn cứ copy code vào rồi chạy thử là thấy.

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trước 1 5 4 8 7 9 5 6 3 2 1
    Sau : 1 4 8 7 9 6 3 2 1 5 5
    Cắt phần màu đỏ: 1 4 8 7 9 6 3 2 1

    Thì bạn bỏ 2 số 5 ra sau như vậy thì có phải là bạn phải dồn mảng ko [IMG]images/smilies/biggrin.png[/IMG]
    Vậy mình nói xóa là đúng rồi, còn dồn mảng xong rồi phía sau bạn ghi zero vào là xong ah.

  5. #5
    Chào bạn , trandinhnamvn !

    Bạn không thể làm nhập nhằn như vậy, vì làm như vậy code của bạn rồi lắm. Tôi phân tích cho bạn thấy mình cần phải làm những gì nhé :
    - thứ nhất cần hàm nhập (ở đây bạn viết trong main rồi)
    - thứ hai cần một hàm xuất mảng
    - thứ ba cần mạng hàm kiểm tra trong mảng các tồn tại số n hay không
    - thứ thư là hàm xóa các phần tử có giá trị n

    Bạn tham khảo code sau nhé, hy vọng bạn sẽ hiểu


    #include <iostream>
    using namespace std;

    int checkexist(int a[],int num,int n)
    {
    for(int i=0;i<num;i++)
    {
    if(a[i]==n)
    return i;
    }
    return -1;
    }
    void deletearr(int a[],int num,int n)
    {
    while(checkexist(a,num,n) != -1)
    {
    int k=checkexist(a,num,n);
    a[num] =0;
    for(int j=k;j<num;j++)
    {
    a[j] =a[j+1];
    }
    }
    }
    void printArray(int a[],int num)
    {
    for (int i = 0; i < num; i++){
    cout << "a["<< i <<"]:"<<a[i];
    cout << endl;
    }
    }


    int main(){
    int a[10], n;
    cout << "Chuan bi nhap vao mot mang:" << endl;
    for (int i = 0; i < 10; i++){
    cout << "Nhap vao phan tu thu " << i << ": ";
    cin >> a[i];
    cout << endl;
    }
    cout << "Nhap vao mot gia tri: ";
    cin >> n;
    deletearr(a,10,n);
    printArray(a,10);
    cin >> n;
    return 0;
    }
    Thêm về kỹ thuật xóa :


  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    ^ Cái này vẫn còn rối lắm [IMG]images/smilies/biggrin.png[/IMG]
    Với lại có thể xóa được bằng 1 for duy nhất.

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Mã:
    1 5 4 8 7 9 5 6 3 2 1
    ^read
    ^write
    a[read] == 1 => != 5, gán a[write] = a[read] và tăng read, write thêm 1 đơn vị


    Mã:
    1 5 4 8 7 9 5 6 3 2 1
      ^read
      ^write
    a[read] == 5, tăng read 1 đơn vị


    Mã:
    1 5 4 8 7 9 5 6 3 2 1
        ^read
      ^write
    a[read] == 4 => != 5, gán a[write] = a[read] và tăng read, write thêm 1 đơn vị


    Mã:
    1 4 4 8 7 9 5 6 3 2 1
          ^read
        ^write
    a[read] == 8 => != 5, gán a[write] = a[read] và tăng read, write thêm 1 đơn vị


    Mã:
    1 4 8 8 7 9 5 6 3 2 1
            ^read
          ^write
    a[read] == 7 => != 5, gán a[write] = a[read] và tăng read, write thêm 1 đơn vị


    Mã:
    1 4 8 7 7 9 5 6 3 2 1
              ^read
            ^write
    a[read] == 9 => != 5, gán a[write] = a[read] và tăng read, write thêm 1 đơn vị


    Mã:
    1 4 8 7 9 9 5 6 3 2 1
                ^read
              ^write
    a[read] == 5, tăng read thêm 1 đơn vị


    Mã:
    1 4 8 7 9 9 5 6 3 2 1
                  ^read
              ^write
    a[read] == 6 => != 5, gán a[write] = a[read] và tăng read, write thêm 1 đơn vị


    Mã:
    1 4 8 7 9 6 5 6 3 2 1
                    ^read
                ^write
    a[read] == 3 => != 5, gán a[write] = a[read] và tăng read, write thêm 1 đơn vị


    Mã:
    1 4 8 7 9 6 3 6 3 2 1
                      ^read
                  ^write
    a[read] == 2 => != 5, gán a[write] = a[read] và tăng read, write thêm 1 đơn vị


    Mã:
    1 4 8 7 9 6 3 2 3 2 1
                        ^read
                    ^write
    a[read] == 1 => != 5, gán a[write] = a[read] và tăng read, write thêm 1 đơn vị


    Mã:
    1 4 8 7 9 6 3 2 1 2 1
                          ^read
                      ^write
    read > sizeof a => khi nào write < sizeof a thì gán a[write] = 0 rồi tăng write thêm 1 đơn vị


    Mã:
    1 4 8 7 9 6 3 2 1 0 1
                        ^write
    Mã:
    1 4 8 7 9 6 3 2 1 0 0
                          ^write
    in kết quả cuối cùng là xong @_@ Ko cần phải dồn hết mảng mỗi khi gặp a[i] == n.

  8. #8
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Một cách khác cho bạn

    Mã:
    void printArray(int a[10], int n){    int     i,j,d2=0;    for(i=0; i<10; i++)    {        if(a[i] == n)        {            for(j=i; j<9-d2; j++)                a[j]    = a[j+1];            a[j] = 0;            d2++;            i--;        }        else            cout << a[i] << "  ";    }}

  9. #9
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi hoangtu_codon_14
    Chào bạn , trandinhnamvn !

    Bạn không thể làm nhập nhằn như vậy, vì làm như vậy code của bạn rồi lắm. Tôi phân tích cho bạn thấy mình cần phải làm những gì nhé :
    - thứ nhất cần hàm nhập (ở đây bạn viết trong main rồi)
    - thứ hai cần một hàm xuất mảng
    - thứ ba cần mạng hàm kiểm tra trong mảng các tồn tại số n hay không
    - thứ thư là hàm xóa các phần tử có giá trị n

    Bạn tham khảo code sau nhé, hy vọng bạn sẽ hiểu



    Thêm về kỹ thuật xóa :

    Mình đã hiểu cách xóa này, nhưng nếu như chạy bằng tay thì mình chưa hiểu lắm.

    VD.

    Nhập dãy 1 2 2 3 4 5 6 7 8 9 và số 2

    Thì khi i=1, dãy xóa số 2 và còn

    1 2 3 4 5 6 7 8 9 0

    Vậy tiếp theo dãy sẽ chạy ntn? Nếu tăng i lên là 2 thì sẽ bị mất đi số 2 còn lại. Nhưng chạy bằng IDE thì vẫn cho ra kq đúng, thế nên mình chưa hiểu cách chạy đoạn chương trình này ntn?

  10. #10
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    ^ Mình cũng... ko hiểu [IMG]images/smilies/biggrin.png[/IMG]

    Dùng cách của INTP sẽ dễ hình dung hơn [IMG]images/smilies/smile.png[/IMG]

 

 
Trang 1 của 2 12 CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •