Nhờ giúp giải mã caesar bằng c++

Quân đội Ấn Độ chuẩn bị tổ chức một cuộc tập kích bất ngờ vào một thành phố của Pakistan. Tổng thống Ấn Độ, Tổng tham mưu của quân đội Ấn Độ sẽ gửi một thông điệp đến tất cả các Trung tâm chỉ huy.

Lo sợ các thông điệp này sẽ bị quân địch theo dõi, quân đội Ấn Độ đã mã hóa những thông điệp này sử dụng một kĩ thuật mã hóa cơ bản. Khóa giải mã “K” sẽ được gửi đến các Trung tâm chỉ huy một cách bí mật.

Bạn được thuê để thiết kế để phát triển chương trình mã hóa các thông điệp. Chương trình của bạn phải quay vòng từng kí tự của thông điệp đi K vị trí để khiến quân địch không thể đọc được.

Viết hàm string cipher (int k, string message) nhận 2 tham số đầu vào là khóa giải mã K và thông điệp message. Hàm trả về thông điệp đã được mã hóa theo khóa K

Lưu ý: Hàm chỉ mã hóa các kí tự và số (A−Z,a−z và 0−9). Tất cả các kí tự khác được giữ nguyên.

#include <bits/stdc++.h>
using namespace std;
string cipher (int k, string s) {
    int l= s.size();
    for (int i=0; i<l; i++) {
        if ('A'<=s[i] && s[i] <='Z') {
            if (k>26)k=k%26;
            if(s[i]+k>'Z') {
                s[i]= s[i]+k -'Z'-1+'A';
            } else s[i]=s[i]+k;
        }
        if ('a'<=s[i] && s[i] <='z') {
            if (k>26) k=k%26;
            if(s[i]+k>'z') {
                s[i]= s[i]+k -'z'-1+'a';
            } else s[i]=s[i]+k;
        }
        if ('0'<=s[i] && s[i] <='9') {
            if(k>10) k=k%10;
            if(s[i]+k>'9') {
                s[i]= s[i]+k -'9'-1+'0';
            } else s[i]=s[i]+k;
        }
    }
    return s;
}
int main() {
    int k;
    string message;
    cin >> k >> message;
    cout << cipher(k, message);
}

em viết code như thế này nhưng có một vài trường hợp lại không ra đáp án đúng
ví dụ như : k=23 và s= “rotating” thì sẽ ra đáp án đúng còn nếu s=“5-rotating” thì lại ra sai
anh chị xem giúp em xem sai ở đâu với ạ

Vì ở trường hợp chữ số thì bạn đã thay đổi biến k mất rồi.

Để xử lí gọn hơn thì tính riêng số rồi mới cộng với ký tự.
VD số thì lấy (c - '0' + k) % 10 + '0'.

3 Likes

k đã bị đổi giá trị khi vào trường hợp số.
Nếu gồm cả 3 trường hợp thì nó sẽ loạn xì ngầu luôn.
Bạn nên dùng biến tạm tách biệt với k để tính phần chia dư.

dạ em cảm ơn mọi người nhiều ạ

sửa đề lại thành (const int k) luôn, thế là hết mắc sai lầm nữa bạn

1 Like

Vấn đề trong hàm mã hóa của bạn đó phát sinh khi biểu thức kiểm tra ký tự không hợp lệ. Hãy cùng nhau cải thiện việc mã hóa dựa trên yêu cầu đã cho.

#include <bits/stdc++.h>
using namespace std;

string cipher(int k, string s) {
    int l = s.size();
    for (int i = 0; i < l; i++) {
        if (isalpha(s[i])) { // Kiểm tra nếu là kí tự chữ
            char base = (isupper(s[i])) ? 'A' : 'a'; // Xác định kí tự in hoa hoặc thường
            s[i] = base + (s[i] - base + k) % 26; // Áp dụng phương pháp quay vòng 26 kí tự
        } else if (isdigit(s[i])) { // Kiểm tra nếu là số
            s[i] = '0' + (s[i] - '0' + k) % 10; // Áp dụng phương pháp quay vòng 10 số
        }
    }
    return s;
}

int main() {
    int k;
    string message;
    cin >> k >> message;
    cout << cipher(k, message);
}

Trong mã cải thiện, mình sử dụng hàm isalpha để kiểm tra xem ký tự có phải là ký tự chữ không, và isupper để xác định xem ký tự đó là in hoa hay in thường. cái này sẽ giúp mã hóa đúng các ký tự chữ và số mà không cần phải căn chỉnh với giá trị k và quy luật mã hóa.

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