30/09/2018, 16:03

Tìm và đếm số từ

string s1="hom nay troi co nang"; s2="hom nay troi khong co mua";

Tìm và đếm số lần xuất hiện của những từ có trong cả 2 xâu s1 và s2.
Giúp em ý tưởng thuật toán với ạ.

Đỗ Trung Quân viết 18:16 ngày 30/09/2018

Bạn dùng sub_string.find(str); nhé

Nguyễn Minh Dũng viết 18:11 ngày 30/09/2018

Có một mẹo như thế này, trước hết em tách hết các từ đó ra. Sau đó em dùng set hoặc unordered_set (chỉ có trong C++11) để thêm các từ trong s1 và s2.

Điểm đặc biệt set là tập không chấp nhận trùng, nên khi em insert các từ vào, thì hàm insert sẽ trả ra một pair Trong đó phần tử đầu tiên pair::first là iterator của từ mới được thêm vào, Phần tử thử hai pair::second là bool, trả về true nếu từ đó là từ mới, false nếu từ đó là từ cũ.

Phát Nguyễn viết 18:05 ngày 30/09/2018

E ko hiểu cách của a @ltd lắm
Em làm kiểu thủ công, nó bị dài

string kq[100];
	int sotu = 0, i = 0;
	int solan[100] = {0};

	while(i < S1.size()){
		
		string temp = "";
		while(i < S1.size() && S1[i] == ' ' || S1[i] == '\t' && i < S1.size())  i++;
		
		while(i < S1.size() && S1[i] != ' ' && S1[i] != '\t' && i < S1.size()) {
			temp += S1[i];
			i++;
		
		}
		int dd = 1;
		for(int j = 1; j <= sotu; j++){
			if(kq[j] == temp) {
				solan[j] += 1;
				dd = 0;
				break;
			}
		}
		if(dd == 1) {
			sotu++;
			kq[sotu] = temp;
			solan[sotu] = 1;
		}
		
	}

Còn dùng cách của @Is2IT là như thế nào vậy, chỉ rõ cho mình với

sub_string.find(str)

Đỗ Trung Quân viết 18:03 ngày 30/09/2018

Srr, mình đọc nhầm đề bài. Tưởng bạn nói tìm số lần của 1 từ trong 1 str. Cái hàm find kia trả về vị trí của sub_string trong string, nếu nó trả về >0 thì có suất hiện. = -1 là không có.
Còn nếu bạn muốn tìm trong 2 string thì mình có ý tưởng thôi. Máy mình hiện tại không code test đc. Chạy onl hơi lâu
Theo cách dài mà dễ hiểu thì

   string s1="hom nay troi co nang va nang rat to"; 

   string s2="hom nay troi khong co mua";

Đếm số từ bất kỳ suất hiện trong string 1. vi du tu "nang" // count =2;
So sánh từ "nang" với các từ string con lai. Neu la "nang" thi count++;
Đỗ Trung Quân viết 18:10 ngày 30/09/2018

Mình nghĩ là chẳng cần tách. Đếm luôn cũng đc. Đếm 2 lần

Phát Nguyễn viết 18:04 ngày 30/09/2018

Thế thì phải cần 1 mảng đánh dấu rồi

Đỗ Trung Quân viết 18:14 ngày 30/09/2018

Ý tưởng của bạn là gì? Mình chỉ đếm rồi in ra count thôi mà,

Phạm Hoàng Tuấn viết 18:12 ngày 30/09/2018

Ý a @ltd là bạn tách hết các từ trong 2 chuỗi, sẽ có 11 từ gồm “Hom, nay…”

Bạn tạo 2 Set (coi như là 1 tập hợp hay danh sách) để chứa 2 chuỗi s1, s2 của bạn.

     //std::set<string> myset1 (chứa s1)
    // std::set<string> myset2 (chứa s2).
    
    std::set<std::string> myset1 = {"hom ", "hom ", "hom ", "hom "....}; //tuong tu cho set 2
    
    
    bool temp1;
    bool temp2;
    
    //sau đó, với 11 từ trên, duyet tat ca cac tu , ta có
    temp1 = myset1.insert(tu1); 
    temp2 = myset2.insert(tu1); 
    if(temp1==temp2==false) //tu1 tồn tại cả trong s1 và s2
    {
    //do something
    }

Đây là ý tưởng chính thôi, bnj tự làm chi tiết nhé. link ví dụ về set : http://www.cplusplus.com/reference/set/set/insert/

Đỗ Trung Quân viết 18:07 ngày 30/09/2018

Đó cũng là 1 cách, hoặc dùng find(str) như mình nói

 find(sub_str) tìm từ "nang" trong str1. Nếu nó có xuất hiện thì count1++
 find(sub_str) tìm từ "nang" trong str2. Nếu nó có xuất hiện thì count2++
 count = count1 + count2;
Đỗ Trung Quân viết 18:06 ngày 30/09/2018

Còn dùng cách của @Is2IT là như thế nào vậy, chỉ rõ cho mình với

Is2IT:
sub_string.find(str)

#include <string>
#include <iostream>
using namespace std;
int Count( const string & str, const string & obj ) {
    int n = 0;
    string ::size_type pos = 0;
    while( (pos = obj.find( str, pos )) != string::npos ) {
    	n++;
    	pos += str.size();
    }
    return n;
}

int main() {
    string s = "How do you do at home";
    string s2 = "Do do am do do arre dooooo";
    string s3 = "do";
    int n = Count( s3, s );
    int m = Count( s3, s2);
    cout <<"This word ("<<s3<<") appear = "<< n +m <<" times in s1 vs s2 "<<endl;
}
Tran Huan viết 18:04 ngày 30/09/2018

Fun with STL, các bạn góp ý nhé

#include <iostream>
#include <string>
#include <iterator>
#include <sstream>
#include <vector>

int main(int argc, const char * argv[]) {
    std::stringstream textstream1, textstream2;
    textstream1 << "Hello, I'm a software engineer. I just want to test some function";
    textstream2 << "Hello, I am a doctor. I want to help people";
    
    // Split words & copy to two difference list
    std::istream_iterator<std::string> in1(textstream1), end;
    std::istream_iterator<std::string> in2(textstream2);
    
    std::vector<std::string> list1(in1, end);
    std::vector<std::string> list2(in2, end);

    // Sort list
    std::sort (list1.begin(), list1.end());
    std::sort (list2.begin(), list2.end());
    
    // Copy duplicates words to v list
    std::vector<std::string> v(list1.size());
    std::vector<std::string>::iterator it;
    it = std::set_intersection (list1.begin(), list1.end(), list2.begin(), list2.end(), v.begin());
    v.resize(it-v.begin());
    
    // Print duplicate words was found
    std::cout << "The intersection has " << (v.size()) << " elements:\n";
    for (it=v.begin(); it!=v.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';
    
    return 0;
}
Nguyễn Minh Dũng viết 18:14 ngày 30/09/2018

Hay đấy, hôm trước anh cũng tính dùng cái std::set_intersection mà sợ bạn @phatnguyen chưa nắm STL không làm được.

Mà hình như code của @tranhuanltv thiếu #include <algorithm> rồi, hàm sort lỗi.

P/S: Nắm STL làm được nhiều trò hay nhỉ. Huân làm C++ giờ là trùm lắm rồi. Nói về C++ thì Huân làm giỏi hơn anh.

Tran Huan viết 18:12 ngày 30/09/2018

Clang vẫn biên dịch được. Thực ra em mới tìm hiểu về STL để thử giải quyết bài toán này thôi anh. Giỏi khỉ gì đâu hehe

Nguyễn Minh Dũng viết 18:13 ngày 30/09/2018

Oh, giờ em dùng clang à, chứng tỏ dạo này nghiên cứu sâu nhỉ.
Anh tính làm cLang từ lâu lắm rồi, trong mấy cái rss vẫn lưu clang vào mà tới giờ cũng chưa đụng vào.

Phát Nguyễn viết 18:08 ngày 30/09/2018

Thật sự là e đọc ko hiểu e làm cách truyền thống thôi, bookmark cái này lại đã, sẽ có lúc học STL dùng đến, cảm ơn các anh

Bài liên quan
0