We are given a personal information string S, which may represent either an email address or a phone number.

We would like to mask this personal information according to the following rules:

1. Email address:

We define a name to be a string of length ≥ 2consisting of only lowercase letters a-z or uppercase letters A-Z.

An email address starts with a name, followed by the symbol '@', followed by a name, followed by the dot '.' and followed by a name.

All email addresses are guaranteed to be valid and in the format of "[email protected]".

To mask an email, all names must be converted to lowercase and all letters between the first and last letter of the first name must be replaced by 5 asterisks '*'.

2. Phone number:

A phone number is a string consisting of only the digits 0-9or the characters from the set {'+', '-', '(', ')', ' '}. You may assume a phone number contains 10 to 13 digits.

The last 10 digits make up the local number, while the digits before those make up the country code. Note that the country code is optional. We want to expose only the last 4 digits and mask all other digits.

The local number should be formatted and masked as "***-***-1111", where 1 represents the exposed digits.

To mask a phone number with country code like "+111 111 111 1111", we write it in the form "+***-***-***-1111".  The '+' sign and the first '-' sign before the local number should only exist if there is a country code.  For example, a 12 digit phone number mask should start with "+**-".

Note that extraneous characters like "(", ")", " ", as well as extra dashes or plus signs not part of the above formatting scheme should be removed.

Return the correct "mask" of the information provided.

Example 1:

Input: "[email protected]"
Output: "l*****[email protected]"
Explanation: All names are converted to lowercase, and the letters between the
  first and last letter of the first name is replaced by 5 asterisks.
  Therefore, "leetcode" -> "l*****e".

Example 2:

Input: "[email protected]"
Output: "a*****[email protected]"
Explanation: There must be 5 asterisks between the first and last letter
  of the first name "ab". Therefore, "ab" -> "a*****b".

Example 3:

Input: "1(234)567-890"
Output: "***-***-7890"
Explanation: 10 digits in the phone number, which means all digits make up the local number.

Example 4:

Input: "86-(10)12345678"
Output: "+**-***-***-5678"
Explanation: 12 digits, 2 digits for country code and 10 digits for local number.

Notes:

  1. S.length <= 40.
  2. Emails have length at least 8.
  3. Phone numbers have length at least 10.
 

這道題讓我們給個人資訊打碼,在這個注重保護隱私的時代,打碼什麼的都是家常便飯了,想看高清無碼的,那就得掏錢。這裡對郵箱和電話分別進行了不同的打碼方式,對於郵箱來說,只保留使用者名稱的首尾兩個字元,然後中間固定加上五個星號,還有就是所有的字母轉小寫。對於電話來說,有兩種方式,有和沒有國家代號,有的話其前面必須有加號,跟後面的區域號用短槓隔開,後面的10個電話號分為三組,個數分別為3,3,4。每組之間還是用短槓隔開,除了最後一組的數字保留之外,其他的都用星號代替。弄清楚了題意,就開始解題吧。既然是字串的題目,那麼肯定要遍歷這個字串了,我們關心的主要是數字和字母,所以要用個變數str來儲存遍歷到的數字和字母,所以判斷,如果是數字或者小寫字母的話,直接加入str中,若是大寫字母的話,轉成小寫字母再加入str,如果遇到了 ‘@’ 號,那麼表示當前處理的是郵箱,而此時的使用者已經全部讀入str了,那直接就取出首尾字元,然後中間加五個星號,並再加上 ‘@’ 號存入結果res中,並把str清空。若遇到了點,說明此時是郵箱的後半段,因為題目中限制了使用者名稱中不會有點存在,那麼我們將str和點一起加入結果res,並將str清空。當遍歷結束時,若此時結果res不為空,說明我們處理的是郵箱,那麼返回結果res加上str,因為str中存的是 "com",還沒有來得及加入結果res。若res為空,說明處理的是電話號碼,所有的數字都已經加入了str,由於國家代號可能有也可能沒有,所以判斷一下存入的數字的個數,如果超過10個了,說明有國家代號,那麼將超過的部分取出來拼裝一下,前面加 ‘+’ 號,後面加短槓。然後再將10位號碼的前六位的星號格式加上,並加上最後四個數字即可,參見程式碼如下:

解法一:

class Solution {
public:
string maskPII(string S) {
string res = "", str = "";
for (char c : S) {
if (c >= 'a' && c <= 'z') str.push_back(c);
else if (c >= 'A' && c <= 'Z') str.push_back(c + );
else if (c >= '' && c <= '') str.push_back(c);
else if (c == '@') {
res += string(, str[]) + "*****" + string(, str.back()) + "@";
str.clear();
} else if (c == '.') {
res += str + ".";
str.clear();
}
}
if (!res.empty()) return res + str;
int n = str.size();
if (n > ) res += "+" + string(n - , '*') + "-";
res += "***-***-" + str.substr(n - );
return res;
}
};

我們還可以換一種寫法,首先在字串S中找 ‘@’ 號,這是區分郵箱地址和電話號碼的關鍵所在。若沒找到,則按電話號碼的方法處理,跟上面的操作幾乎相同。若找到了,則直接取出第一個字母,加五個星號,然後將 ‘@’ 號位置及其後面所有的字元都加入結果res,然後再統一轉為小寫即可,參見程式碼如下:

解法二:

class Solution {
public:
string maskPII(string S) {
string res = "", str = "";
auto pos = S.find('@');
if (pos == string::npos) {
for (char c : S) {
if (c >= '' && c <= '') str.push_back(c);
}
int n = str.size();
if (n > ) res += "+" + string(n - , '*') + "-";
res += "***-***-" + str.substr(n - );
} else {
res = S.substr(, ) + "*****" + S.substr(pos - );
transform(res.begin(), res.end(), res.begin(), ::tolower);
}
return res;
}
};

參考資料:

https://leetcode.com/problems/masking-personal-information/

https://leetcode.com/problems/masking-personal-information/discuss/129400/Straightforward-C%2B%2B

LeetCode All in One 題目講解彙總(持續更新中...)