10.【动态规划】Decode Ways--Time Limit Exceeded

本文详细解析了LeetCode上的一道经典算法题目——解码方法的数量问题。该问题探讨了如何计算字符串中可能的解码方式总数,并提供了一个递归解决方案。文章通过具体的代码实现展示了不同情况下的解码逻辑。

leetcode url:https://leetcode.com/problems/decode-ways/

public class Solution {
    public int numDecodings(String s) {
        s=s.trim();
        if(s==null || s.equals("") || s.charAt(0)=='0' || s.contains("00")) return 0;
        else if(s.length()==1 && Integer.parseInt(s)==0)
            return 0;
        else if(s.length()==1 && Integer.parseInt(s)!=0)
            return 1;
        else if(s.length()==2 && Integer.parseInt(s)<10){
            return 0;
        }
        else if(s.length()==2 && (Integer.parseInt(s)==10 || Integer.parseInt(s)==20)){
            return 1;
        }
        else if(s.length()==2 && Integer.parseInt(s)>10 && Integer.parseInt(s)<=26 && Integer.parseInt(s)!=20){
            return 2;
        }
        else if(s.length()==2 && Integer.parseInt(s)>26 && s.charAt(s.length()-1)!='0' )
            return 1;
        else if(s.length()==2 && Integer.parseInt(s)>26 && s.charAt(s.length()-1)=='0' )
            return 0;
        else{
            if(s.charAt(s.length()-2)!='0' && s.charAt(s.length()-1)!='0' && Integer.parseInt(s.substring(s.length()-2,s.length()))<=26)
                return numDecodings(s.substring(0,s.length()-2))+numDecodings(s.substring(0,s.length()-1));
            else if(s.charAt(s.length()-2)!='0' && s.charAt(s.length()-1)!='0' && Integer.parseInt(s.substring(s.length()-2,s.length()))>26)
                return numDecodings(s.substring(0,s.length()-1));
            else if(s.charAt(s.length()-2)=='0' && s.charAt(s.length()-1)!='0' && s.charAt(s.length()-3) <'3')
                return numDecodings(s.substring(0,s.length()-1));
            else if(s.charAt(s.length()-2)=='0' && s.charAt(s.length()-1)!='0' && s.charAt(s.length()-3) >='3')
                return 0;
            else if(s.charAt(s.length()-2)!='0' && s.charAt(s.length()-1)=='0' && Integer.parseInt(s.substring(s.length()-2,s.length()))<=26)
                return numDecodings(s.substring(0,s.length()-2));
            else return 0;
        }

    }
}

accepted code见:http://blog.youkuaiyun.com/linhuanmars/article/details/24570759

<think>我们遇到了一个常见的编码问题:当我们尝试使用UTF-8解码响应的内容时,遇到了无效的起始字节(invalid start byte)。这通常意味着实际内容的编码不是UTF-8,或者内容被压缩了。以下是一些解决步骤: ### 步骤1:检查响应头中的编码信息 首先,我们应该检查响应头中指定的字符集。服务器通常在`Content-Type`头中声明编码,例如: ```python import requests resp = requests.get(url, headers=headers, cookies=cookies) print(resp.headers['Content-Type']) ``` 如果输出类似于`text/html; charset=GBK`,那么我们应该使用指定的编码(如GBK)进行解码。 ### 步骤2:使用响应对象的自动解码 `requests`库提供了`resp.text`属性,它会自动根据响应头中的编码信息进行解码。如果响应头中没有指定编码,`requests`会尝试推测编码。因此,我们可以优先使用`resp.text`: ```python print(resp.text) ``` ### 步骤3:处理编码错误 如果`resp.text`仍然出错,或者我们需要手动处理编码,可以尝试以下方法: #### 方法1:尝试常见的中文编码 对于中文网页,常见的编码有`GBK`、`GB2312`、`GB18030`等。我们可以尝试这些编码: ```python print(resp.content.decode('GBK')) # 或 'GB2312', 'GB18030' ``` #### 方法2:使用chardet检测编码 我们可以使用第三方库`chardet`来检测编码: ```python import chardet # 检测内容编码 encoding = chardet.detect(resp.content)['encoding'] print(encoding) # 查看检测到的编码 # 使用检测到的编码进行解码 print(resp.content.decode(encoding)) ``` ### 步骤4:处理压缩内容 有时,服务器返回的内容是压缩过的(如gzip),但`requests`会自动解压缩。不过,如果响应头中`Content-Encoding`是`gzip`,但实际内容未解压,我们可以手动解压: ```python import gzip from io import BytesIO # 如果响应是gzip压缩的,我们可以这样解压 if resp.headers.get('Content-Encoding') == 'gzip': buf = BytesIO(resp.content) f = gzip.GzipFile(fileobj=buf) content = f.read() # 然后尝试解码 print(content.decode('utf-8')) # 或者使用其他编码 else: print(resp.content.decode('utf-8')) ``` ### 步骤5:忽略错误或替换非法字符 如果上述方法都不行,我们可以在解码时忽略错误或替换非法字符: ```python # 忽略无法解码的字节 print(resp.content.decode('utf-8', errors='ignore')) # 或者用问号替换非法字节 print(resp.content.decode('utf-8', errors='replace')) ``` ### 实际应用示例 结合以上方法,我们可以编写一个健壮的解码函数: ```python import requests import chardet def safe_decode(content, default_encoding='utf-8'): try: # 先尝试使用默认编码(UTF-8)解码 return content.decode(default_encoding) except UnicodeDecodeError: # 如果失败,使用chardet检测编码 encoding = chardet.detect(content)['encoding'] if encoding is None: # 如果检测不到,尝试常见的中文编码 for enc in ['GBK', 'GB18030', 'GB2312', 'ISO-8859-1']: try: return content.decode(enc) except UnicodeDecodeError: continue # 如果都不行,忽略错误 return content.decode(default_encoding, errors='ignore') else: try: return content.decode(encoding) except UnicodeDecodeError: return content.decode(default_encoding, errors='ignore') # 使用示例 resp = requests.get(url, headers=headers, cookies=cookies) decoded_content = safe_decode(resp.content) print(decoded_content) ``` ### 总结 出现`invalid start byte`错误的主要原因是编码不匹配。解决步骤包括: 1. 检查响应头中的编码信息 2. 使用`resp.text`自动解码 3. 尝试常见中文编码 4. 使用`chardet`检测编码 5. 处理可能的压缩内容 6. 忽略错误或替换非法字符 通过以上方法,我们可以有效解决解码错误问题[^1][^2][^3]。 §§相关问题§§ 1. 如何检测网页的真实编码? 2. Python中处理文本编码的最佳实践有哪些? 3. 为什么有些网页使用非UTF-8编码? 4. 如何避免在爬虫中遇到编码问题?</think>## 解决 requests 中 `decode('utf-8')` 的 "invalid start byte" 错误 当使用 `response.content.decode('utf-8')` 时遇到 "invalid start byte" 错误,通常是因为实际内容编码与 UTF-8 不匹配。以下是系统化的解决方案: ### 1. 检查响应头中的编码信息(推荐) 优先使用响应头中声明的编码: ```python resp = requests.get(url, headers=headers, cookies=cookies) encoding = resp.encoding # 自动检测的编码 print(encoding) # 查看实际检测到的编码 print(resp.text) # 自动使用正确编码解码 ``` ### 2. 尝试常见中文编码 当响应头未指定编码时,尝试以下中文常用编码: ```python for encoding in ['GBK', 'GB2312', 'GB18030', 'ISO-8859-1']: try: print(resp.content.decode(encoding)) break # 成功解码则跳出循环 except UnicodeDecodeError: continue ``` ### 3. 使用 chardet 自动检测编码 安装检测库:`pip install chardet` ```python import chardet # 检测内容编码 result = chardet.detect(resp.content) print(f"检测到的编码: {result['encoding']}, 置信度: {result['confidence']}") # 使用检测结果解码 decoded_content = resp.content.decode(result['encoding']) print(decoded_content) ``` ### 4. 处理压缩内容 当服务器返回压缩内容时: ```python # 检查是否压缩 if 'gzip' in resp.headers.get('Content-Encoding', ''): import gzip from io import BytesIO # 解压gzip内容 buffer = BytesIO(resp.content) with gzip.GzipFile(fileobj=buffer) as f: decompressed = f.read() print(decompressed.decode('utf-8')) # 再尝试解码 ``` ### 5. 安全解码选项 忽略错误或替换无效字节: ```python # 忽略无效字节 print(resp.content.decode('utf-8', errors='ignore')) # 用?替换无效字节 print(resp.content.decode('utf-8', errors='replace')) ``` ### 6. 最佳实践:通用解码函数 ```python def safe_decode(content): encodings = ['UTF-8', 'GBK', 'ISO-8859-1', 'latin1'] for enc in encodings: try: return content.decode(enc) except UnicodeDecodeError: continue # 所有编码都失败时使用替换 return content.decode('utf-8', errors='replace') # 使用示例 print(safe_decode(resp.content)) ``` ### 关键点总结 1. **优先使用`resp.text`**:requests 会自动处理编码 2. **检查响应头**:`Content-Type`中的`charset`参数最重要 3. **中文网站常用编码**:GBK/GB2312 > UTF-8 > ISO-8859-1 4. **压缩内容**:检查`Content-Encoding`头处理gzip压缩 5. **动态检测**:使用chardet库提高解码成功率[^1][^2][^3] > **经验提示**:抖音等短视频平台常使用GBK编码而非UTF-8,优先尝试GBK系列编码可解决90%以上的中文解码问题[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值