1044. 火星数字(20)-PAT乙级真题

本文介绍了一个实用工具,能够实现地球数字与火星数字间的相互转换。采用13进制的火星数字系统,拥有独特的高位和低位表示法。通过解析输入字符串,判断其类型并进行相应的转换。

火星人是以13进制计数的:地球人的0被火星人称为tret。地球人数字1到12的火星文分别为:jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec。火星人将进位以后的12个高位数字分别称为:tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou。例如地球人的数字“29”翻译成火星文就是“hel mar”;而火星文“elo nov”对应地球数字“115”。为了方便交流,请你编写程序实现地球和火星数字之间的互译。

输入格式

输入第一行给出一个正整数N(<100),随后N行,每行给出一个[0, 169)区间内的数字 —— 或者是地球文,或者是火星文。

输出格式

对应输入的每一行,在一行中输出翻译后的另一种语言的数字。

输入样例

4
29
5
elo nov
tam

输出样例

hel mar
may
115
13

分析:因为给出的可能是数字(地球文)也有可能是字母(火星文),所以用字符串s保存每一次的输入,因为如果是火星文则会出现空格,所以用getline接收一行的输入~计算string s的长度len,判断s[0]是否是数字,如果是数字,表示是地球文,则需要转为火星文,执行func1();如果不是数字,则说明是火星文,需要转为地球文,执行func2();

func1(int t)中,传入的值是string转int后的结果stoi(s),因为数字最大不超过168,所以最多只会输出两位火星文,如果t / 13不等于0,说明有高位,所以输出b[t/13];如果输出了高位(t/13不等于0)并且t % 13不等于0,说明有高位且有低位,所以此时输出空格;如果t % 13不等于0,说明有低位,此时输出a[t % 13];注意,还有个数字0没有考虑,因为数字0取余13等于0,但是要特别输出tret,所以在func1的最后一句判断中加一句t == 0,并将a[0]位赋值成tret即可解决0的问题~

func2()中,t1和t2一开始都赋值0,s1和s2用来分离火星文单词,因为火星文字符串只可能一个单词或者两个单词,而且一个单词不会超过4,所以先将一个单词的赋值给s1,即s1 = s.substr(0, 3);如果len > 4,就将剩下的一个单词赋值给s2,即s2 = s.substr(4, 3);然后下标j从1到12遍历a和b两个数组,如果a数组中有和s1或者s2相等的,说明低位等于j,则将j赋值给t2;如果b数组中有和s1相等的(b数组不会和s2相等,因为如果有两个单词,s2只可能是低位),说明高位有值,将j赋值给t1,最后输出t1 * 13 + t2即可~

#include <iostream>
#include <string>
using namespace std;
string a[13] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
string b[13] = {"####", "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
string s;
int len;
void func1(int t) {
    if (t / 13) cout << b[t / 13];
    if ((t / 13) && (t % 13)) cout << " ";
    if (t % 13 || t == 0) cout << a[t % 13];
}
void func2() {
    int t1 = 0, t2 = 0;
    string s1 = s.substr(0, 3), s2;
    if (len > 4) s2 = s.substr(4, 3);
    for (int j = 1; j <= 12; j++) {
        if (s1 == a[j] || s2 == a[j]) t2 = j;
        if (s1 == b[j]) t1 = j;
    }
    cout << t1 * 13 + t2;
}
int main() {
    int n;
    cin >> n;
    getchar();
    for (int i = 0; i < n; i++) {
        getline(cin, s);
        len = s.length();
        if (s[0] >= '0' && s[0] <= '9')
            func1(stoi(s));
        else
            func2();
        cout << endl;
    }
    return 0;
}

根据你提供的 SQL 查询结果,当前查询返回了两条数据,且 `exposureDuration` 为 `0.17` 和 `-0.37`,说明: - **存在重复数据**(相同的 `CUSTLOTID` 和 `GROUPID`) - **存在负数暴露时长**(`unpack_time < pack_time`) --- ### ✅ 问题分析 #### 1. **为什么出现两条数据?** 你当前的 SQL 是将 `tb_lmms_hbm_material_info` 左连接到一个子查询 `c`,而子查询 `c` 返回了多个 `GROUPID` 的记录,导致主表记录被重复显示。 #### 2. **为什么出现负数暴露时长?** 说明在子查询中,`h2.OPERATETIME < h1.OPERATETIME`,即退料时间早于发料时间。 --- ### ✅ 解决方案 #### ✅ 1. 确保子查询中每组 `GROUPID` 只保留一条记录(避免重复) ```sql SELECT h1.CUSTLOTID, h1.GROUPID, MIN(h1.OPERATETIME) AS pack_time, -- 确保取最早发料时间 MIN(h2.OPERATETIME) AS unpack_time -- 确保取最早退料时间 FROM TB_LMMS_HBM_MATERIAL_HIST h1 JOIN TB_LMMS_HBM_MATERIAL_HIST h2 ON h1.CUSTLOTID = h2.CUSTLOTID AND h1.GROUPID = h2.GROUPID WHERE h1.ISSUANCEUSER IS NOT NULL AND h2.RETURNUSER IS NOT NULL AND h2.OPERATETIME > h1.OPERATETIME -- 仅保留退料时间 > 发料时间的记录 GROUP BY h1.CUSTLOTID, h1.GROUPID ``` --- #### ✅ 2. 修改主 SQL,避免重复展示主表数据 ```java sql = " SELECT a.*, b.materialName reelMaterialName, c.exposureDuration " + " FROM tb_lmms_hbm_material_info a " + " LEFT JOIN tb_reel_material_maintain b ON a.sapMaterialNo = b.sapMaterialNo " + " LEFT JOIN ( " + " SELECT " + " h1.CUSTLOTID, " + " h1.GROUPID, " + " ROUND((MIN(h2.OPERATETIME) - MIN(h1.OPERATETIME)) * 24, 2) AS exposureDuration " + " FROM TB_LMMS_HBM_MATERIAL_HIST h1 " + " JOIN TB_LMMS_HBM_MATERIAL_HIST h2 " + " ON h1.CUSTLOTID = h2.CUSTLOTID AND h1.GROUPID = h2.GROUPID " + " WHERE h1.ISSUANCEUSER IS NOT NULL " + " AND h2.RETURNUSER IS NOT NULL " + " AND h2.OPERATETIME > h1.OPERATETIME " + " GROUP BY h1.CUSTLOTID, h1.GROUPID " + " ) c ON a.CUSTLOTID = c.CUSTLOTID AND c.GROUPID IS NOT NULL " + " WHERE 1=1 "; ``` --- ### ✅ 优化建议 | 问题 | 建议 | |------|------| | 主表记录重复 | 使用 `GROUP BY` 或 `DISTINCT` 避免主表重复 | | 暴露时长为负 | 在子查询中加入 `h2.OPERATETIME > h1.OPERATETIME` 条件 | | 多个 `GROUPID` 导致多条记录 | 使用聚合函数 `MIN()` 或 `MAX()` 确保每组只取一条记录 | | 性能问题 | 为 `CUSTLOTID`, `GROUPID`, `OPERATETIME` 建立索引 | --- ### ✅ 示例输出(修复后) ``` CUSTLOTID: JE04018 GROUPID: 1 pack_time: 2025-09-28 08:42:38 unpack_time: 2025-09-28 11:10:59 exposureDuration: 2.47 小时 ``` ---
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值