登录
OAmaster

Complete the Message class to handle processing of messages between a sender and a receiver. Implement the following methods:

class Message(object):
    def __init__(self, message: str, sender: int, receiver: int) -> None: pass
    def __str__(self) -> str: pass
    def __eq__(self, o: object) -> bool: pass
  • __init__: store the message, sender, receiver as instance variables.
  • __str__: return the message text (without sender/receiver).
  • __eq__: two messages are equal iff their message attributes (text) are the same. Sender and receiver do not affect equality.

Example

message1 = Message("Hello", 1, 2)
message2 = Message("Hello World", 3, 2)
message3 = Message("Hello", 2, 1)
print(message1) # Hello
message1 == message2 # False
message1 == message3 # True

Constraints

  • Maximum number of messages ≤ 50
  • Maximum message length ≤ 100 words
  • Sender and Receiver are integers between 0 and 100

解法

标准 OOP。把 messagesenderreceiver 存为字段。__str__ 返回 self.message__eq__ 只比较 message。重写 __eq__ 后必须同时重写 __hash__(按 message 哈希),对象才可哈希。Java/C++ 对应重写 equals/hashCodeoperator==。所有操作复杂度 O(L)L 为消息长度。

class Message:
    def __init__(self, message: str, sender: int, receiver: int) -> None:
        self.message = message
        self.sender = sender
        self.receiver = receiver

    def __str__(self) -> str:
        return self.message

    def __eq__(self, o: object) -> bool:
        return isinstance(o, Message) and self.message == o.message

    def __hash__(self) -> int:
        return hash(self.message)
class Message {
    String message;
    int sender, receiver;

    Message(String m, int s, int r) {
        this.message = m;
        this.sender = s;
        this.receiver = r;
    }

    @Override public String toString() { return message; }

    @Override public boolean equals(Object o) {
        if (!(o instanceof Message)) return false;
        return message.equals(((Message) o).message);
    }

    @Override public int hashCode() { return message.hashCode(); }
}
struct Message {
 string message;
 int sender, receiver;

 Message(string m, int s, int r) : message(move(m)), sender(s), receiver(r) {}

 string str() const { return message; }

 bool operator==(const Message& o) const {
 return message == o.message;
 }
};

struct MessageHash {
 size_t operator()(const Message& m) const { return hash<string>()(m.message); }
};

There are two tables: sales_amount and exchange_rate. When the exchange rate changes, a new row is inserted into exchange_rate with a new effective_start_date for that (source, target) pair.

Write a query that returns the total sales amount in USD for each sales_date, rounded to two decimals (with trailing zeros), ordered by sales_date.

Schema:

sales_amount(sales_date varchar, sales_amount int, currency varchar)
exchange_rate(source_currency varchar, target_currency varchar, exchange_rate numeric(18,2), effective_start_date varchar)

Sample data:

sales_amount:
2020-01-01 500 INR
2020-01-01 100 GBP
2020-01-02 1000 INR
2020-01-02 500 GBP
2020-01-03 500 INR
2020-01-17 200 GBP

exchange_rate:
INR USD 0.14 2019-12-31
INR USD 0.15 2020-01-02
GBP USD 1.32 2019-12-20
GBP USD 1.30 2020-01-01
GBP USD 1.35 2020-01-16

Expected output:

2020-01-01 200.00
2020-01-02 800.00
2020-01-03 75.00
2020-01-17 270.00

解法

对每笔销售,选取该币种到 USD、effective_start_datesales_date 的最晚一条汇率。典型 as-of join 模式:相关子查询或窗口函数(按 effective_start_date desc 排名)。再按日期 SUM(sales_amount * rate)。在 (source_currency, effective_start_date) 上加索引后复杂度 O(N log N)

SELECT s.sales_date,
 ROUND(SUM(s.sales_amount * r.exchange_rate), 2) AS total_usd
FROM sales_amount s
JOIN exchange_rate r
 ON r.source_currency = s.currency
 AND r.target_currency = 'USD'
 AND r.effective_start_date = (
 SELECT MAX(r2.effective_start_date)
 FROM exchange_rate r2
 WHERE r2.source_currency = s.currency
 AND r2.target_currency = 'USD'
 AND r2.effective_start_date <= s.sales_date
 )
GROUP BY s.sales_date
ORDER BY s.sales_date;