01/10/2018, 09:52
Gặp lỗi trong đoạn code đếm số lượng từ
Xin chào mn, hiện tại mình đang làm 1 bài tập liên quan đến chuỗi là đếm số lượng từ có trong một chuỗi cho trước. Code của mình hoạt động cũng khá ổn những khi chuỗi dài & phức tạp thì có sai số (so với số liệu khi paste lên WORD).
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
// Viết hàm nhận vào một chuỗi s và đếm xem có bao nhiêu từ trong chuỗi đó.
int countWord(char *);
bool checkAlphabet(char);
int main()
{
char str[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ut magna fringilla, volutpat orci in, suscipit ligula. Maecenas nec urna vel risus vehicula pellentesque. Proin non ex sed erat dignissim finibus eu vitae orci. Curabitur feugiat sem in iaculis pulvinar. Suspendisse non orci tristique mauris vestibulum rutrum non at arcu. Morbi a tortor mi. Sed dictum quam in massa accumsan, eu volutpat orci sagittis. Vivamus vehicula in quam iaculis accumsan. Donec sed egestas massa, ut semper nulla. Vivamus accumsan est id urna vulputate iaculis. In vitae blandit felis. Nullam feugiat ipsum vel volutpat malesuada. Donec sed dictum nisi. Curabitur vitae efficitur purus. Donec laoreet a arcu nec viverra.";
printf("str has %d word(s).
", countWord(str));
return 0;
}
int countWord(char *str)
{
size_t size = strlen(str);
int word = 0;
if (checkAlphabet(str[0]) && checkAlphabet(str[1]))
++word;
for (int i = 1; i < size - 1; ++i) {
if (str[i - 1] == ' ' && checkAlphabet(str[i]) && checkAlphabet(str[i + 1]))
++word;
}
return word;
}
bool checkAlphabet(char ch)
{
return (65 <= ch && ch <= 90) || (97 <= ch && ch <= 122);
}
Code của mình cho kq là 106 words, trong khi Word là 108 words !! Mình tìm hoài ko ra nó sai chỗ nào, nhờ mn xem giúp nhé, xin cảm ơn trc
Bài liên quan
Một ví dụ cực kì dễ thấy là từ
a
(tronglike a boy
chẳng hạn). Trước chữ a và sau chữ a đều là dấu cách, nhưnga
vẫn là 1 từ. Định nghĩa 1 từ là 1 xâu nằm giữa 2 dấu cách hoặc từ kí tự đầu tiên đến trước dấu cách đầu tiên hoặc từ dấu cách cuối cùng đến dấu các cuối cùng. Định nghĩa trên khác hoàn toàn với câu lệnh if của bạn.Có thể dùng bool flag để xử lí dùng rồi sẽ thấy logic bài này đơn giản cực kì.
Ok cảm ơn bạn nhé, thì ra là cái định nghĩa về từ của mình nó ko giống như Word :))[quote=“rogp10, post:3, topic:47337”]
Có thể dùng bool flag để xử lí
[/quote]
Bạn nói rõ hơn về cái bool flag cho mình thử xem :)) mình chưa nghe từ đó bao h
Trong C++ có cấu trúc hashtable là map đó bạn, tham khảo cách hoạt động của nó.
Boolean flag là biến lưu trạng thái với chỉ hai giá trị true và false. Điều kiện rất đơn giản nên ta xét từng kí tự với một flag là đủ.
Chẳng ai lại đi gõ ra những thứ không-thể-nhìn-được như các ký tự điều khiển nên hàm
checkAlphabet
là không cần thiết.Nếu xét 1 chuỗi được gõ đúng quy tắc: các dấu (phẩy, chấm,…) nằm ngay sau từng từ, chỉ có 1 khoảng trắng ở giữa các từ, đầu và đuôi chuỗi không có các khoảng trắng thì hàm
countWord
chỉ cần đếm khoảng trắng và cộng thêm 1 (vì cuối chuỗi không có khoảng trắng) rồi trả về.Theo mình thì gõ các văn bản thì chả ai làm sai mấy quy tắc trên nên không sao :v Còn nếu mà có người nào xàm xí đi test kiểu vi phạm hết các quy tắc trên thì bạn cần viết thêm hàm chỉnh chuỗi lại cho đúng quy tắc rồi triển thôi.
Code
Vậy làm bằng cách nào đc bạn?
Ừm, mục đích ban đầu của mình là làm cho đúng hết mọi trường hợp có thể đó bạn, chứ nếu mà source string đó được viết theo đúng quy tắt thì tuyệt quá Nói cách khác, mình muốn code hoạt động sao cho giống thằng Word nhất có thể
Nhưng mà nó mất công với lại kêu đếm thì chỉ cần đếm thôi chứ tại sao lại đi sửa của người ta vậy
Để mở rộng code thì nên thay hàm checkAlphabet() bằng
isWhitespace()
.Tức là bạn dùng biến flag
whitespaceFlag
sau đó bạn xác định khi nào toggle flag này (bt trong đa số thời gian chạy flag này không đổi) và viết code thôi.convert tất cả những thứ không phải alphabet và digit thành whitespace, rồi đưa vào chuỗi thứ 2 từng ký tự một, đồng thời lọc theo quy tắc:
whitespace đầu tiên: loại
nếu chuỗi thứ 2 kết thúc bằng whitespace: không thêm whitespace
cuối cùng: đếm số white space
nếu chuỗi thứ 2 không kết thúc bằng whitespace: giảm đi 1
return