Tìm kiếm 1 chuỗi trong 1 đoạn văn bản?

Mọi người cho ý kiến em dùng hàm này được k? nhưng đây chỉ là tìm chuỗi đầu tiên :((

CIRC đơn giản chỉ là một chuỗi thôi anh (nó là biến chạy đường tròn của robot anh ạ). Thực ra chuỗi lớn đó có rất nhiều CIRC, nhưng em chỉ đưa đoạn code ví dụ thôi, trong đó xuất hiện 1 lần anh ạ :stuck_out_tongue:

Ví dụ nó như thế nào đi? Vấn đề có vẻ đơn giản mà em phức tạp hóa nó lên. Anh chả hiểu CIRC là cái gì?

Xuất hiện chỗ nào đâu?

Thế này cho đơn giản đi anh.
Một đoạn văn bản dài khoảng 3 trang. Tìm chữ Thanh xuất hiện đầu tiên và cuối cùng trong văn bản đó. Và đưa ra vị trí của chúng.

Thế làm sao để đưa ra địa chỉ của từ “vu” hả anh?

Thuật toán này chưa tối ưu, nhưng nó có thể giải quyết vấn đề của bạn

#include <iostream>
#include <cstring>

using namespace std;
void all_match(char *text,char* patt){
   char *p=text;
   for(;;){ 
       p=strstr(p,patt);
       if(p==NULL){
           break;
       }
       int vitri= p-text;
       printf("match at: %d\n",vitri);
       p=p+1;
   }
}
int main() {
	all_match("daynhauhoc.com & portal.daynhauhoc.com", "hoc");
	return 0;
}

Câu hỏi thế này thì quá đơn giản :smile: Em cứ cho CIRC vào làm gì cho phức tạp.

Ở đây anh dùng hàm

  • std::find để tìm chữ Thanh đầu tiên.
  • std::rfind để tìm chữ Thanh cuối cùng.
#include <iostream>       // std::cout
#include <string>         // std::string

int main () {
    std::string vanBan("Mot doan van ban dai 3 trang co chu Thanh o day va mot chu Thanh nua o day");
    std::string chuoi("Thanh");

    std::size_t found = vanBan.find(chuoi);
    if (found!=std::string::npos)
        std::cout << "Chu " << chuoi <<" dau tien nam o: " << found << '\n';

    found = vanBan.rfind(chuoi);
    if (found!=std::string::npos)
        std::cout << "Chu " << chuoi <<" cuoi cung nam o: " << found << '\n';
    return 0;
}
1 Like

em muốn viết một hàm tìm kiếm kí tự “ABC” trong một văn bản mà người dùng nhập vào. Anh có thể đề xuất cho em được ko ạ :smiley:

em dùng hàm fgets để nhập chuỗi nhé

tức là em muốn kiểm tra xem trong văn bản có chứa kí tự “ABC” ko ấy ạ…

Trong ví dụ trên em chỉ cần thay “Thanh” sang “ABC” là được rồi cơ mà?

#include <iostream>       // std::cout
#include <string>         // std::string

int main () {
    std::string vanBan("Mot doan van ban dai 3 trang co chu Thanh o day va mot chu Thanh nua o day");
    std::string chuoi("ABC");

    std::size_t found = vanBan.find(chuoi);
    if (found!=std::string::npos)
        std::cout << "Chu " << chuoi <<" dau tien nam o: " << found << '\n';

    found = vanBan.rfind(chuoi);
    if (found!=std::string::npos)
        std::cout << "Chu " << chuoi <<" cuoi cung nam o: " << found << '\n';
    return 0;
}

anh có thể giải thích giúp em npos ở if (found!=std::string::npos) là hàm gì ko ạ :smiley:

std::string::npos dùng để chỉ số dương lớn nhất của kiểu dữ liệu size_t. Biến này sẽ được gán bằng -1. Bởi vì size_t bản chất là kiểu unsigned int, nên khi ta gán bằng -1, nó sẽ chuyển thành số dương lớn nhất có thể của kiểu dữ liệu đó.

static const size_t npos = -1;

Em có thể hiểu một cách đơn giản, anh đang muốn kiểm tra rằng cái biến found đó, có phải là một kết quả đúng hay không. Nếu found trả về số khác -1, tức là ta đã tìm được vị trí của chuoi.

Đây là một cách làm hợp lệ, được khuyến khích sử dụng thay vì so sánh

if (found != -1)

rất cảm ơn anh :smiley: nhờ anh mà em đã giải quyết được 3 bài, còn 10 bài mai làm nốt vậy :))

1 Like

Bởi vì em là người đã tạo cái topic hỏi bài tập nên anh nhắc thêm một tí ngoài lề.

Sau này đừng lập topic theo dạng chụp màn hình hoặc gửi toàn bộ đề bài lên nữa. Cố gắng suy nghĩ giải pháp để giải bài tập trước, nếu hoàn toàn không giải được thì em có thể ghi hẳn ra, em đã suy nghĩ mà không có giải pháp. Hoặc, em có giải pháp thế này thế kia nhưng không xử lý được.

Hỏi như thế sẽ kích thích người trả lời, và đồng thời cũng tạo cho em thói quen suy nghĩ trước khi hỏi. Đó là điều kiện tiên quyết để giúp em học giỏi trong nhiều lĩnh vực chứ không chỉ trong lập trình không thôi.

Chúc em học tốt với daynhauhoc nhé :smile:

Anh cho em hỏi mấy chỗ được không ạ:

  1. Em thay lệnh std::size_t found = vanBan.find_first_of(“Thanh”); bằng std::size_t found = vanBan.find(chuoi); được k anh?
  2. vanBan mình khai báo như thê nào? tức là đưa cái văn bản có trước vào chương trình này như thê nào ạ? Chứ em không thể copy 3 trang văn bản đó vào chương trình được, k lẽ nó dài 100 trang thì tât nhiên là k khả thi đúng k anh?
  3. Khi mình đưa kết quả found ra ngoài thì kết quả như thê nào ạ? Có phải là địa chỉ mình đang đi tìm không? found nó ở dạng biến gì hả anh?
    Em cần dùng cái địa chỉ đó để thêm vào một chuỗi mới “Chu” chẳng hạn và trc “Thanh” thì em có thể hiểu vanBan[found] k anh?

Em dễ dàng có thể thử và đưa ra kết luận mà.

Đây là cách anh ví dụ, còn chả ai làm thế. Em phải lưu văn bản xuống file, sau đó dùng C++ đọc nội dung file lên.

found là vị trí của chữ Thanh trong vanBan. Ví dụ

abcd
0123

Chữ c có vị trí 2

Đúng

Thế có topic nào nói về cách mở file bằng C++ không anh? Và C++ có thể mở được những file gì ạ?

Em cám ơn anh nhiều!

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?