Trang 1 / 2 12 LastLast
Hiển thị kết quả từ 1 đến 10 / 11

Chủ đề: Chuỗi kí tự!

  1. #1
    Tham gia
    31-07-2011
    Bài viết
    57
    Like
    17
    Thanked 32 Times in 32 Posts

    Chuỗi kí tự!

    Đây là bài em tự làm: "Tìm số kí tự có trong mảng"
    Code:
    #include <stdio.h>
    #include <conio.h>
    #include <iostream>
    void main()
    {
    	int l;
    	int k=0;
    	char s1[50], s2[50];
    	printf("Insert a string: ");
    	gets(s1);
    	l = strlen(s1);
    	for (int i = 0; i < l; i++)
    	{
    		int flag =0;
    		for (int j=0; j < i; j++)
    			if (s1[i] == s1[j])
    				flag++;
    		if (flag == 0)
    		{
    			s2[k] = s1[i];
    			k++;
    		}
    	};
    	s2[k] = '\0';
    	printf("The string has %d characters!\n", strlen(s2));
    	system("pause");
    }
    Em test thử vài lần thì thấy nó chạy đúng, nhưng các bác xem giùm em làm vậy có dài quá ko? Có cách nào ngắn hơn/hay hơn ko?
    Thanks
    Quote Quote

  2. Thành viên Like bài viết này:


  3. #2
    Tham gia
    02-05-2011
    Bài viết
    133
    Like
    0
    Thanked 67 Times in 49 Posts
    Nếu chỉ đếm số kí tự thì bạn có thể làm như thế này:
    Code:
    char flag[256];
    memset(flag, 0, sizeof(flag));
    
    int count = 0;
    int len = strlen(s);
    int i;
    for(i = 0; i < len; ++i)
    {
             if(flag[s[i]] == 0)
             {
                     flag[s[i]] = 1;
                     ++count;
             }
    }
    
    printf("The string has %d characters!\n", count);
    s là chuỗi cần đếm, count là kết quả

    Còn nếu muốn có chuỗi s2 như bạn ở trên thì có thể sửa lại:

    Code:
    char flag[256];
    memset(flag, 0, sizeof(flag));
    
    int count = 0;
    int len = strlen(s);
    int i;
    for(i = 0; i < len; ++i)
    {
             if(flag[s[i]] == 0)
             {
                     s2[count] = s[i];
                     flag[s[i]] = 1;
                     ++count;
             }
    }
    s2[count] = NULL;
    printf("The string has %d characters!\n", count);
    printf("s2 = %s", s2);
    p/s: bài của bạn khi flag++; thì ko cần phải cho chạy vòng lặp for bên trong làm j nữa bạn à.
    Được sửa bởi predator0906 lúc 18:14 ngày 15-09-2011

  4. Thành viên Like bài viết này:


  5. #3
    Tham gia
    31-07-2011
    Bài viết
    57
    Like
    17
    Thanked 32 Times in 32 Posts
    Cho em hỏi
    Code:
     memset(flag, 0, sizeof(flag));
    nghĩa là gì ?

  6. Thành viên Like bài viết này:


  7. #4
    Tham gia
    02-05-2011
    Bài viết
    133
    Like
    0
    Thanked 67 Times in 49 Posts
    http://www.cplusplus.com/reference/c...string/memset/

    Set giá trị cho bộ nhớ bạn à. Ở trên mình thiết lập nó về 0

  8. 2 thành viên Like bài viết này:


  9. #5
    Tham gia
    31-07-2011
    Bài viết
    57
    Like
    17
    Thanked 32 Times in 32 Posts
    Tình hình là vẫn ko hiểu lắm đoạn code bác viết. Bác giải thích thêm giùm em đc ko? (Cả bài luôn ấy)

    Em chỉ mới học những thứ căn bản nhất của C, theo bác khi nào bài có nên tìm cách làm hiệu quả nhất/ngắn nhất hay tạm thời chỉ cần giải quyết đc bài toán trc, khi nào học nhiều hơn rồi nghiên cứu vấn đề đó sau?

  10. Thành viên Like bài viết này:


  11. #6
    Tham gia
    02-05-2011
    Bài viết
    133
    Like
    0
    Thanked 67 Times in 49 Posts
    Quote Được gửi bởi hell_angel7602 View Post
    Tình hình là vẫn ko hiểu lắm đoạn code bác viết. Bác giải thích thêm giùm em đc ko? (Cả bài luôn ấy)

    Em chỉ mới học những thứ căn bản nhất của C, theo bác khi nào bài có nên tìm cách làm hiệu quả nhất/ngắn nhất hay tạm thời chỉ cần giải quyết đc bài toán trc, khi nào học nhiều hơn rồi nghiên cứu vấn đề đó sau?
    char flag[256];
    memset(flag, 0, sizeof(flag));

    => flag dùng để đánh dấu xem kí tự đã được đếm hay chưa, nếu đã đếm nó rồi thì ko cần đếm lại.
    Nếu flag[i] == 0 nghĩa là chưa đếm kí tự này, nếu flag[i] == 1 thì kí tự này đã đếm rồi. VD:

    s = "abcab";

    vòng lặp for sẽ chạy qua từng kí tự trong s

    Ở mỗi vị trí của s, nó sẽ kiểm tra flag tương ứng. Vì là bảng mã ANSI nên chỉ có 256 loại kí tự, do đó biến flag ở vị trí tương ứng sẽ dùng để đánh dấu cho kí tự này.

    Bây giờ mình chạy từng bước thì bạn sẽ dễ hiểu hơn:

    Khởi tạo count = 0;
    Bước 1: i = 0 : s[i] = 'a', lúc này flag[s[i]] = flag['a'] = 0 nên 'a' chưa đc đếm => ++count đồng thời gán flag['a'] = 1 (đánh dấu đã đếm 'a')
    Bước 2: i = 1 : s[i] = 'b', lúc này flag[s[i]] = flag['b'] = 0 nên 'b' chưa đc đếm => ++count, gán flag['b'] = 1;
    Bước 3: i = 2 : s[i] = 'c', lúc này flag[s[i]] = flag['c'] = 0 nên 'c' chưa đc đếm => ++count, gán flag['c'] = 1;
    Bước 4: i = 3 : s[i] = 'a', lúc này flag[s[i]] = flag['a'] = 1 nên 'a' đã được đếm ở trên => ko làm j cả
    Bước 5: i = 4 : s[i] = 'b', lúc này flag[s[i]] = flag['b'] = 1 nên 'b' đã được đếm ở trên => ko làm j cả

    Vì ++count 3 lần nên chuỗi này có 3 loại kí tự


    p/s: Bài mình chỉ khác của bạn ở chỗ. Mình dùng mảng flag[256] để đánh dấu xem kí tự đã đếm chưa. còn bài bạn thì dùng vòng for bên trong để kiểm tra xem kí tự đó đã có ở phía trước(tức là được đếm) hay chưa, nếu có thì bạn ko đếm nữa còn ko có thì bạn đếm kí tự này.

    Khi làm bài thi, tất nhiên mình sẽ chọn cách nào dễ làm nhất để làm, vì mục đích lúc này là làm đúng và nhanh. Còn nếu làm bài tập nào đó như bài tập lớn chẳng hạn, thì nhà trường có thể yêu cầu chạy nhanh, vì họ tạo ra các testcase để chấm, nếu chạy quá thời gian thì coi như ko đạt, do đó lúc này phải chú ý làm cho nó chạy nhanh rồi.

    VD: nếu đề thi cho: viết 1 giải thuat săp xep mảng. Thì có rat nhiều giải thuat sap xếp như: insertion sort, bubble sort, quick sort, heap sort, selection sort... Nhưng chắc chắn mình sẽ chọn bubble sort hoặc selection sort để làm rồi, vì nó dễ làm, dễ hiẻu & ngắn :d

    Nói chung trước tiên bạn phải suy nghĩ để làm được trước đã, còn chuyện chạy nhanh thì để tính sau, từ từ sửa lại
    Được sửa bởi predator0906 lúc 12:01 ngày 19-09-2011

  12. 2 thành viên Like bài viết này:


  13. #7
    Tham gia
    31-07-2011
    Bài viết
    57
    Like
    17
    Thanked 32 Times in 32 Posts
    Cho em hỏi cách làm việc với chuỗi mà ko bị giới hạn bởi bộ nhớ dành riêng cho chuỗi đó.
    VD em nhập chuỗi đầu là "ABCD" thì chiều dài chuỗi là 4, thêm 1 với chiều dài bất kì vào chuỗi đầu tiên mà ko bị báo lỗi.

    Kiểu khai báo chuỗi dạng con trỏ hằng char str[100] và con trỏ char * str; thì cái nào có lợi hơn, trường hợp nào thì dùng loại nào?

  14. Thành viên Like bài viết này:


  15. #8
    Tham gia
    04-10-2011
    Bài viết
    15
    Like
    3
    Thanked 6 Times in 5 Posts
    em mới tham gia vào ddth nên không biết làm thế nào để code của mình đóng khung như vây?

  16. Thành viên Like bài viết này:


  17. #9
    Tham gia
    29-05-2011
    Location
    Hà Nội
    Bài viết
    1,826
    Like
    1,420
    Thanked 47 Times in 42 Posts
    Quote Được gửi bởi luubahung1312 View Post
    em mới tham gia vào ddth nên không biết làm thế nào để code của mình đóng khung như vây?
    bạn viết như thế này nè:

  18. #10
    Tham gia
    11-10-2011
    Bài viết
    5
    Like
    1
    Thanked 0 Times in 0 Posts
    nếu có kí tụe trắng thì hắn có đếm ko?

Trang 1 / 2 12 LastLast

Bookmarks

Quy định

  • Bạn không thể tạo chủ đề mới
  • Bạn không thể trả lời bài viết
  • 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
  •