返回

如何让每个人的电子邮件地址都独一无二?模拟题进阶解法

后端

问题概述

在现实世界中,电子邮件地址的格式往往是多种多样的。例如,以下几个电子邮件地址都属于同一个人:

  • john.smith@example.com
  • john.smith@example.co.uk
  • john.smith123@example.com
  • john.smith_99@example.com

很显然,这些电子邮件地址虽然看起来不同,但实际上都指向同一个邮箱。为了方便管理和避免混淆,我们需要一种方法来将这些电子邮件地址规范化,使其具有唯一性。

规范化算法

为了实现电子邮件地址的规范化,我们可以使用以下算法:

  1. 将电子邮件地址中的所有大写字母转换为小写字母。
  2. 去除电子邮件地址中的所有点(.)。
  3. 去除电子邮件地址中的所有连字符(-)。
  4. 去除电子邮件地址中的所有下划线(_)。
  5. 将电子邮件地址中的所有数字移到电子邮件地址的末尾。
  6. 在电子邮件地址的末尾添加一个“+”号。

例如,根据上述算法,电子邮件地址john.smith@example.com将被规范化为johnsmith+0@example.com

编程实现

为了帮助大家更好地理解和应用电子邮件地址规范化算法,我们使用Python、C++、Java和JavaScript四种编程语言实现了该算法。

Python

def normalize_email(email):
  """
  规范化电子邮件地址。

  Args:
    email: 要规范化的电子邮件地址。

  Returns:
    规范化后的电子邮件地址。
  """

  # 将电子邮件地址中的所有大写字母转换为小写字母。
  email = email.lower()

  # 去除电子邮件地址中的所有点(`.`)。
  email = email.replace(".", "")

  # 去除电子邮件地址中的所有连字符(`-`)。
  email = email.replace("-", "")

  # 去除电子邮件地址中的所有下划线(`_`)。
  email = email.replace("_", "")

  # 将电子邮件地址中的所有数字移到电子邮件地址的末尾。
  digits = ""
  for char in email:
    if char.isdigit():
      digits += char
  email = email.replace(digits, "")
  email += digits

  # 在电子邮件地址的末尾添加一个“+”号。
  email += "+"

  # 返回规范化后的电子邮件地址。
  return email


if __name__ == "__main__":
  # 测试用例。
  test_cases = [
    "john.smith@example.com",
    "john.smith@example.co.uk",
    "john.smith123@example.com",
    "john.smith_99@example.com",
  ]

  # 输出规范化后的电子邮件地址。
  for test_case in test_cases:
    normalized_email = normalize_email(test_case)
    print(f"{test_case} -> {normalized_email}")

C++

#include <iostream>
#include <string>

using namespace std;

string normalize_email(string email) {
  // 将电子邮件地址中的所有大写字母转换为小写字母。
  for (int i = 0; i < email.size(); i++) {
    email[i] = tolower(email[i]);
  }

  // 去除电子邮件地址中的所有点(`.`)。
  email.erase(remove(email.begin(), email.end(), '.'), email.end());

  // 去除电子邮件地址中的所有连字符(`-`)。
  email.erase(remove(email.begin(), email.end(), '-'), email.end());

  // 去除电子邮件地址中的所有下划线(`_`)。
  email.erase(remove(email.begin(), email.end(), '_'), email.end());

  // 将电子邮件地址中的所有数字移到电子邮件地址的末尾。
  string digits;
  for (char c : email) {
    if (isdigit(c)) {
      digits += c;
    }
  }
  email.erase(remove_if(email.begin(), email.end(), [](char c) { return isdigit(c); }), email.end());
  email += digits;

  // 在电子邮件地址的末尾添加一个“+”号。
  email += "+";

  // 返回规范化后的电子邮件地址。
  return email;
}

int main() {
  // 测试用例。
  vector<string> test_cases = {
    "john.smith@example.com",
    "john.smith@example.co.uk",
    "john.smith123@example.com",
    "john.smith_99@example.com",
  };

  // 输出规范化后的电子邮件地址。
  for (string test_case : test_cases) {
    string normalized_email = normalize_email(test_case);
    cout << test_case << " -> " << normalized_email << endl;
  }

  return 0;
}

Java

import java.util.Arrays;

public class EmailNormalization {

  public static void main(String[] args) {
    // 测试用例。
    String[] testCases = {
      "john.smith@example.com",
      "john.smith@example.co.uk",
      "john.smith123@example.com",
      "john.smith_99@example.com",
    };

    // 输出规范化后的电子邮件地址。
    for (String testCase : testCases) {
      String normalizedEmail = normalizeEmail(testCase);
      System.out.println(testCase + " -> " + normalizedEmail);
    }
  }

  private static String normalizeEmail(String email) {
    // 将电子邮件地址中的所有大写字母转换为小写字母。
    email = email.toLowerCase();

    // 去除电子邮件地址中的所有点(`.`)。
    email = email.replace(".", "");

    // 去除电子邮件地址中的所有连字符(`-`)。
    email = email.replace("-", "");

    // 去除电子邮件地址中的所有下划线(`_`)。
    email = email.replace("_", "");

    // 将电子邮件地址中的所有数字移到电子邮件地址的末尾。
    String digits = "";
    for (char c : email.toCharArray()) {
      if (Character.isDigit(c)) {
        digits += c;
      }
    }
    email = email.replaceAll("[0-9]", "");
    email += digits;

    // 在电子邮件地址的末尾添加一个“+”号。
    email += "+";

    // 返回规范化后的电子邮件地址。
    return email;
  }
}

JavaScript

const normalizeEmail = (email) => {
  // 将电子邮件地址中的所有大写字母转换为小写字母。
  email = email.toLowerCase();

  // 去除电子邮件地址中的所有点(`.`)。
  email = email.replace(/\./g, "");

  // 去除电子邮件地址中的所有连字符(`-`)。
  email = email.replace(/-/g, "");

  // 去除电子邮件地址中的所有下划线(`_`)。
  email = email.replace(/_/g, "");

  // 将电子邮件地址中的所有数字移到电子邮件地址的末尾。
  const digits = email.match(/\d+/g);
  email = email.replace(/\d+/g, "");
  email += digits ? digits.join("") : "";

  // 在电子邮件地址的末尾添加一个“+”号。
  email += "+";

  // 返回规范化后的电子邮件地址。
  return email;
};

const testCases = [
  "john.smith@example.com",
  "john.smith@example.co.uk",
  "john.smith123@example.com",
  "john.smith_99@example.com",
];

for (const testCase of testCases) {
  const normalizedEmail = normalizeEmail(testCase);
  console.log(`${testCase} -> ${normalizedEmail}`);
}

优势和局限

电子邮件地址规范化算法具有以下优势: