Tại sao phải thêm @ vào sau chuỗi trong bài tập về stack

include <iostream>
#include <stack>
#include <string>
using namespace std;

string to_string(long long n){
    string s = "";
    while (n > 0){
        s = char (n%10 + '0') + s;
        n /= 10;
    }
    return s;
}
int main(){
	string s;
	getline(cin, s);
	s=s+"@";
 	stack<char> st;
 	string a ="";
 	for(int i =0;i<s.length();i++){
        if(st.empty() == true || s[i]==st.top()){
            st.push(s[i]);
        } else{
            int count = 0;
            a = a + st.top();
            while(st.empty()!=true){
                count ++;
                st.pop();
            }
            a = a+to_string(count);
            st.push(s[i]);
        }
 	}
 	cout << a;
}

cho em hỏi tại sao phải thêm @ vào sau chuỗi ạ??

Đây gọi là kỹ thuật lính canh.
Khoan hãy quan tâm tới tại sao lại thêm "@", bạn có hiểu chương trình này làm gì với s, st và a không?
Sau khi chạy hết chương trình thì s, st và a có giá trị là gì?
Nếu không thêm "@" thì s, st và a có giá trị là gì?
Từ đó tự nhiên bạn sẽ hiểu tại sao lại phải thêm thôi.

6 Likes

Em tự viết không có dòng thêm @ thì chữ cái cuối cùng không hiện ra. Em xem đáp án lại thấy có thêm dòng này thêm váo thì chữ cái cuối cùng nó lại hiện ra. Em cũng không hiểu lắm.
Vd code em viết nhập aabbcc thì nó ra a2b2 còn thêm dòng này vào nó ra được cả a2b2c2.

Mình hỏi bạn quá chừng câu hỏi mà bạn trả lời hời hợt ghê. Mấy cái câu hỏi bạn không trả lời chính là mấu chốt làm bạn không hiểu đó.

5 Likes

Em hiểu mà!!!
Đầu tiên sẽ có 1 string s. stack st dùng để lưu lần lượt các phần tử giống nhau của s r đếm số lần xuất hiện sau đó xóa đi r thêm phần tử tiếp theo r lại đếm … a là chuỗi lưu kí tự và số lần xuất hiện để in ra màn hình. em chỉ không hiểu cái @ thôi ạ

Ak em hiểu r em cảm ơn anh ạ. Có phải là phải có kí tự @ nó khác với kí tự cuối để biến đếm cộng thêm 1 và string a + thêm kí tự cuối và dếm xong in ra ạ

2 Likes

Đang định reply để blame mà coi như bạn kịp quay đầu vậy =]]

Nếu không thêm lính canh @ vào, thì bạn sẽ phải xét thêm bước cuối cùng với các phần từ còn dư lại trong st để in ra thêm 1 lần nữa. Có @ rồi thì reuse được đoạn code sẵn có trong vòng lặp luôn. Nhưng đúng là ký tự @ phải khác ký tự cuối trong chuỗi s mới được.

Lần sau, có người reply hỏi thì cố gắng đọc kỹ các câu hỏi và trả lời hết càng chi tiết càng tốt nha bạn. Ít ai rảnh rỗi hỏi mấy câu vớ vẩn lắm :stuck_out_tongue:

4 Likes

Vâng ạ. Em sẽ rút kinh nghiệm ạ. Em cảm ơn anh.

1 Like

Thực ra bài này chỉ cần 1 counter thôi :slight_smile:

Bài này ko dùng lính canh thì cuối vòng lặp phải lặp lại đoạn code đếm số lần lặp kí tự.

3 Likes

cần 2 dòng là đủ rồi :V

#include <iostream>
#include <string>
#include <algorithm>

int main() {
    std::string s;
    std::getline(std::cin, s);
    for (decltype(s)::iterator it = begin(s), it2; it != end(s); it = it2)
        std::cout << *it << std::distance(it, it2 = std::find_if(it, end(s), [&](char c) { return c != *it; }));
}
4 Likes

Ui cái này khó thế để em tìm hiểu từ từ ạ. Em cảm ơn ạ!!!

1 Like

Thật sự là newb đọc ko hiểu đoạn trên đâu :slight_smile: khoan đã.

Con trỏ (vẽ hình ra nhé) 1 trỏ vào vị trí đầu dãy lặp và con trỏ 2 từ 1 đi đến khi nào gặp kí tự khác 1, hoặc hết chuỗi. Lúc này ko cần sentinel nữa vì điều kiện hết chuỗi sẽ làm ngừng vòng lặp trong và kích hoạt code xử lí.

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