原理

问题目标:根据读者的查询条件,统计图书编码中满足特定后缀要求的数量。每个查询给出后缀长度(num)和对应的编码值(code),需检查图书编码的最后num位是否与code匹配。


步骤

  1. 输入数据
    • 读取图书数量 n 和查询次数 q
    • 读取 n 个图书编码(整数形式)。
  2. 处理查询
    • 对每个查询,读取 num(后缀长度)和 code(目标后缀值)。
    • 将 code 转换为字符串。
    • 遍历所有图书编码,将其转换为字符串后截取最后 num 位,与 code 的字符串比较。
  3. 统计结果:记录匹配的图书数量并输出。

图示法表示步骤(示例:n=3q=1num=2code=34

  1. 输入图书编码
    Book Codes: [1234, 56789, 34]  
  2. 查询处理
    • code 转换为字符串 "34"
    • 检查每个图书编码的后2位:
      • 1234 → "34"(匹配)
      • 56789 → "89"(不匹配)
      • 34 → "34"(匹配)
    • 输出结果:2

代码关键行注释

// 定义读者查询结构体(包含后缀长度和编码值)  
typedef struct reader {  
    int readerCodeNum;  // 后缀长度  
    int readerCode;     // 目标后缀值(整数形式,但输入时会丢失前导零)  
};  

// 匹配函数:统计图书编码中后 num 位等于 code 的数量  
int matchBook_Reader(vector<int> bookCode, int num, int code) {  
    string code_s = to_string(code);  // 将 code 转为字符串(可能丢失前导零)  
    int ans = 0;  
    for (int i = 0; i < bookCode.size(); i++) {  
        string bookCode_s = to_string(bookCode[i]);  // 图书编码转为字符串  
        if (bookCode_s.size() < num) continue;        // 长度不足则跳过  
        string postcode = bookCode_s.substr(bookCode_s.size() - num); // 截取后 num 位  
        if (postcode == code_s) ans++;                // 字符串比较  
    }  
    return ans;  
}  

// 主函数  
int main() {  
    // 输入图书编码  
    vector<int> bookCode(n);  
    for (int i = 0; i < n; i++) cin >> bookCode[i];  

    // 处理每个查询  
    vector<reader> Reader(q);  
    for (int i = 0; i < q; i++) {  
        cin >> Reader[i].readerCodeNum >> Reader[i].readerCode;  
        // 调用匹配函数并输出结果  
        int ans = matchBook_Reader(bookCode, Reader[i].readerCodeNum, Reader[i].readerCode);  
        cout << ans << endl;  
    }  
    return 0;  
}  

完整代码程序


#include <iostream>
#include <vector>
#include <string>

using namespace std;

typedef struct reader{
    int readerCodeNum;
    int readerCode;
};

int matchBook_Reader(vector<int> bookCode,int num,int code){
    string code_s=to_string(code);
    int ans=0;
    for(int i=0;i<bookCode.size();i++){
        string bookCode_s=to_string(bookCode[i]);
        if(bookCode_s.size()<num) continue;
        string postcode=bookCode_s.substr(bookCode_s.size()-num);
        if(postcode==code_s){
            ans++;
        }
    }
    return ans;
}

int main(){
    int n,q;
    cin>>n>>q;
    vector<int> bookCode(n);
    for(int i=0;i<n;i++){
        cin>>bookCode[i];
    }
    vector<reader> Reader(q);
    for(int i=0;i<q;i++){
        cin>>Reader[i].readerCodeNum>>Reader[i].readerCode;
        int ans=matchBook_Reader(bookCode,Reader[i].readerCodeNum,Reader[i].readerCode);
        cout<<ans<<endl;
    }
    return 0;
}

时间复杂度

  • 时间复杂度:O(q * n * L),其中 L 是图书编码的最大位数。每个查询遍历 n 个图书编码,每个编码需转换为字符串并截取后缀。
  • 空间复杂度:O(n + q),存储图书编码和查询列表。

总结

  1. 代码特点
    • 直接逻辑实现:通过字符串操作检查后缀匹配,代码简洁。
    • 整数转字符串的缺陷:若查询的 code 包含前导零(如 005),输入为整数时会丢失前导零(存储为 5),导致匹配失败。
  2. 潜在问题
    • 前导零处理错误:这是代码的核心问题。例如,图书编码为 1005,查询 num=3code=005,实际 code 会被存储为 5,导致匹配失败。
  3. 优化建议
    • 输入 code 时应直接读取字符串而非整数,以避免前导零丢失。
    • 预处理图书编码为字符串形式,减少重复转换开销。
  4. 适用场景
    • 仅适用于查询的 code 不含前导零的特殊情况,实际题目可能需要修正输入逻辑。
Logo

集算法之大成!助力oier实现梦想!

更多推荐