leetcode-151 翻转字符串里的单词 Python

本文介绍了三种使用Python实现的方法来反转字符串中的单词。第一种方法使用split()和for循环;第二种方法通过删除前后空格、反转整个字符串并再次反转每个单词来实现;第三种方法利用deque进行高效操作。

方法一:

class Solution:
    def reverseWords(self, s: str) -> str:
        a = s.split()
        ans = ""
        for i in range(len(a)-1,-1,-1):
            ans += a[i]
            ans += " "
        return ans.strip()

简化版

class Solution:
    def reverseWords(self, s: str) -> str:
        return " ".join(reversed(s.split()))

方法二:

class Solution:
    def trim_spaces(self, s: str) -> list:
        left, right = 0, len(s) - 1
        # 去掉字符串开头的空白字符
        while left <= right and s[left] == ' ':
            left += 1
        
        # 去掉字符串末尾的空白字符
        while left <= right and s[right] == ' ':
            right -= 1
        
        # 将字符串间多余的空白字符去除
        output = []
        while left <= right:
            if s[left] != ' ':
                output.append(s[left])
            elif output[-1] != ' ':
                output.append(s[left])
            left += 1
        
        return output
            
    def reverse(self, l: list, left: int, right: int) -> None:
        while left < right:
            l[left], l[right] = l[right], l[left]
            left, right = left + 1, right - 1
            
    def reverse_each_word(self, l: list) -> None:
        n = len(l)
        start = end = 0
        
        while start < n:
            # 循环至单词的末尾
            while end < n and l[end] != ' ':
                end += 1
            # 翻转单词
            self.reverse(l, start, end - 1)
            # 更新start,去找下一个单词
            start = end + 1
            end += 1
                
    def reverseWords(self, s: str) -> str:
        l = self.trim_spaces(s)
        
        # 翻转字符串
        self.reverse(l, 0, len(l) - 1)
        
        # 翻转每个单词
        self.reverse_each_word(l)
        
        return ''.join(l)

方法三:

class Solution:
    def reverseWords(self, s: str) -> str:
        left, right = 0, len(s) - 1
        # 去掉字符串开头的空白字符
        while left <= right and s[left] == ' ':
            left += 1
        
        # 去掉字符串末尾的空白字符
        while left <= right and s[right] == ' ':
            right -= 1
            
        d, word = collections.deque(), []
        # 将单词 push 到队列的头部
        while left <= right:
            if s[left] == ' ' and word:
                d.appendleft(''.join(word))
                word = []
            elif s[left] != ' ':
                word.append(s[left])
            left += 1
        d.appendleft(''.join(word))
        
        return ' '.join(d)
<think>好的,用户想了解DDD设计中ServiceDomain Service的区别及应用场景。首先,我需要回顾一下DDD中的相关概念,确保自己理解正确。 根据引用[1],微服务的范围可以对应DDD的限界上下文,而服务对应其中的聚合。这里提到的服务可能是指应用服务。但用户的问题是关于ServiceDomain Service的区别,所以需要明确两者的定义和职责。 在DDD中,通常有三种服务:应用服务(Application Service)、领域服务(Domain Service)和基础服务(Infrastructure Service)。用户可能将应用服务简称为Service,而Domain Service是领域层的服务。需要区分这两者的不同。 应用服务属于应用层,负责协调领域对象、处理事务、安全等应用逻辑,不包含业务规则。例如,创建订单时可能需要调用仓储保存数据,发送消息等,这些是应用服务的职责。 领域服务属于领域层,处理领域内的业务逻辑,尤其是当某个操作不适合放在实体或值对象中时。例如,转账涉及两个账户的余额变更,可能需要在领域服务中处理,确保事务和业务规则。 引用[3]提到上下游上下文的关系,可能涉及服务间的协作,但需要结合例子说明。例如,在电商系统中,订单服务(应用服务)可能调用支付领域服务来处理支付逻辑。 需要举例说明两者的区别。比如,用户注册:应用服务处理用户输入,调用领域服务验证唯一性,保存用户数据,发送欢迎邮件。其中验证唯一性可能由领域服务实现,而发送邮件属于应用服务调用的基础设施。 还要注意领域服务和领域模型的关系。领域服务应专注于业务逻辑,而应用服务协调外部操作。引用[2]提到的领域范围,如YouTube的领域可能涉及视频处理、用户管理等,领域服务处理这些核心业务逻辑。 需要确保回答结构清晰,分点说明区别、职责和例子,并引用相关文献支持。最后生成相关问题,帮助用户深入理解。</think>### DDD设计中ServiceDomain Service的区别及应用场景 在领域驱动设计DDD)中,**Service**和**Domain Service**是两种不同层次的服务,其职责和应用场景有本质区别。以下从定义、职责和示例三方面展开说明: --- #### 1. 定义与层级 - **应用服务(Application Service)** 属于**应用层**,负责协调领域对象、基础设施(如数据库、消息队列)和用户界面。其核心职责是组织业务流程,不包含具体的业务逻辑。例如: ```java public class OrderApplicationService { public void createOrder(OrderDTO orderDTO) { // 调用领域服务验证库存 inventoryService.validateStock(orderDTO); // 调用领域模型创建订单 Order order = OrderFactory.create(orderDTO); // 调用仓储保存数据 orderRepository.save(order); // 发布领域事件(如通知支付系统) eventPublisher.publish(new OrderCreatedEvent(order)); } } ``` [^1] - **领域服务(Domain Service)** 属于**领域层**,封装领域内需要多个领域对象协作的核心业务逻辑。这些逻辑无法直接归属于某个实体(Entity)或值对象(Value Object)。例如: ```java public class TransferService { public void transfer(Account from, Account to, Money amount) { if (from.getBalance() < amount) throw new InsufficientBalanceException(); from.debit(amount); to.credit(amount); // 记录转账流水(需跨实体协作) transactionLogRepository.logTransfer(from, to, amount); } } ``` --- #### 2. 核心职责对比 | **维度** | **应用服务** | **领域服务** | |----------------|---------------------------------------|---------------------------------------| | **所属层级** | 应用层(协调业务流程) | 领域层(实现核心业务规则) | | **依赖关系** | 依赖领域服务和基础设施(如数据库) | 仅依赖领域模型和仓储接口 | | **典型场景** | 用户注册、订单提交、支付回调处理 | 跨聚合操作(如转账)、复杂计算逻辑 | | **业务逻辑** | 不包含领域规则,仅调用领域组件 | 直接实现领域规则 | --- #### 3. 示例场景 **场景1:电商订单创建** - **应用服务**:协调验证库存、调用支付接口、发送通知邮件。 ```java public class OrderAppService { public void createOrder(OrderRequest request) { // 调用领域服务验证库存 stockService.validate(request.getItems()); // 创建订单聚合根 Order order = new Order(request); // 调用支付微服务(基础设施) paymentClient.process(order.getTotal()); // 发送邮件(基础设施) emailService.sendConfirmation(order.getUser()); } } ``` - **领域服务**:计算订单总价(含折扣规则)。 ```java public class PricingService { public Money calculateTotal(List<Item> items, User user) { Money total = items.stream().map(Item::getPrice).sum(); if (user.isVIP()) total = total.multiply(0.9); // VIP折扣 return total; } } ``` **场景2:视频平台内容推荐** - **应用服务**:调用推荐算法、记录用户行为日志。 - **领域服务**:根据用户历史行为生成推荐标签(需跨“用户画像”和“视频元数据”聚合协作)。 --- #### 4. 设计原则 - **领域服务的必要性**:当操作涉及多个实体或需要封装独立业务规则时使用。例如,银行系统中的“汇率转换”应作为领域服务,而非实体方法[^3]。 - **避免贫血模型**:若逻辑可归属到实体内部(如`Order.calculateTotal()`),则优先放在实体中,而非领域服务。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值