PAT 1035 Password (20分) 字符替换

Scroll Down

题目

To prepare for PAT, the judge sometimes has to generate random passwords for the users. The problem is that there are always some confusing passwords since it is hard to distinguish 1 (one) from l (L in lowercase), or 0 (zero) from O (o in uppercase). One solution is to replace 1 (one) by @, 0 (zero) by %, l by L, and O by o. Now it is your job to write a program to check the accounts generated by the judge, and to help the juge modify the confusing passwords.

Input Specification:
Each input file contains one test case. Each case contains a positive integer N (≤1000), followed by N lines of accounts. Each account consists of a user name and a password, both are strings of no more than 10 characters with no space.

Output Specification:
For each test case, first print the number M of accounts that have been modified, then print in the following M lines the modified accounts info, that is, the user names and the corresponding modified passwords. The accounts must be printed in the same order as they are read in. If no account is modified, print in one line There are N accounts and no account is modified where N is the total number of accounts. However, if N is one, you must print There is 1 account and no account is modified instead.

Sample Input 1:

3
Team000002 Rlsp0dfa
Team000003 perfectpwd
Team000001 R1spOdfa

Sample Output 1:

2
Team000002 RLsp%dfa
Team000001 R@spodfa

Sample Input 2:

1
team110 abcdefg332

Sample Output 2:

There is 1 account and no account is modified

Sample Input 3:

2
team110 abcdefg222
team220 abcdefg333

Sample Output 3:

There are 2 accounts and no account is modified

题目解读

大意就是对于密码中的部分字符不易区分,采用替换的策略,用 '@' 代替 '1',用 '%' 替换 '0',用 'L' 替换 'l',用 'o' 替换 'O'

输入 N 个名字和密码(长度都不超过10),如果密码中出现 1 0 l O 就按照上面的规则替换,最后输出替换了多少个密码,逐行输出每一个替换后的 名字 密码(名字不替换),要求这些输出的顺序与输入的顺序一致;如果没有需要替换的,那么如果只有一个输出,就输出 There is 1 account and no account is modified;否则 输出 There are N accounts and no account is modifiedN 是输入的个数。(无非就是单数用is,复数用are)

思路分析

  • 字符替换好处理,只需要逐个判断当前字符,若是 1 0 l O 中的一个,就替换成对应的 @ % L o,否则这个位置的字符不变即可。
  • 只要进行替换,这个密码就是修改了的密码,我们需要保存 名字 修改后的密码,这里你可能会考虑需要队列吗,为了保证输出的顺序和输入的一致,先来先服务?不需要的,我们每读入一个输入,就进行处理,这样就保证了先读入,先处理,只需要按顺序保存即可,所以我们只需要一个vector<string>就好了。
  • 逐个处理完输入后,如果vectorsize()0,就说明没有一个输入需要被处理,此时就根据总的输入数目,输出 There is xxxThere are xxxx了;否则就先输出 size,然后依次输出vector中的每一个元素就好了。

代码

#include <iostream>
#include <vector>
using namespace std;

int main() {

    int n;
    vector<string> modified;

    cin >> n;
    string name, passwd;
    for (int j = 0; j < n; ++j) {
        cin >> name >> passwd;
        // 这个密码是否需要校正
        bool flag = false;
        for (int i = 0; i < passwd.length(); ++i) {
            switch (passwd[i]) {
                // 遇到这四个字符进行替换
                case '1': passwd[i] = '@'; flag = true; break;
                case '0': passwd[i] = '%'; flag = true; break;
                case 'l': passwd[i] = 'L'; flag = true; break;
                case 'O': passwd[i] = 'o'; flag = true; break;
                // 其他字符不改变
                default: break;
            }
        }
        // 这个密码被修改了
        if (flag) 
            // 加入被修改过的集合(按顺序处理的,所以加入之后也是按顺序的)
            modified.push_back(name + " " + passwd);
    }
    // 校正了几个密码
    int num = modified.size();
    if (num > 0) {
        cout << modified.size() << endl;
        // 输出校正后的姓名 密码
        for (string str: modified) 
            cout << str << endl;
    // 没有需要校正的,但是原输入只有一个
    } else if(n == 1) {
        cout << "There is 1 account and no account is modified";
    // 没有需要校正的,并且原输入有多个(is 和 are 的区别)
    } else {
        cout << "There are " << n << " accounts and no account is modified";
    }
    return 0;
}