#P3043. 磁盘容量排序(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 143
            Accepted: 58
            Difficulty: 2
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>字符串          
 
磁盘容量排序(100分)
题目描述
在计算机中,磁盘的容量常用的单位有 M (MB),G (GB),T (TB),它们之间的换算关系如下:
- 1T = 1024G
 - 1G = 1024M
 
现给定 n 块磁盘的容量,每块容量可能由多个单位组成,单位可以是 M、G 或 T。要求按照从小到大的顺序对磁盘容量进行稳定排序。
解题思路
- 
单位转换:为了能进行排序,我们需要将不同单位的容量统一成同一种单位(例如,统一转换为 M)。这样,可以通过直接比较数字大小来进行排序。
 - 
解析字符串:每个磁盘的容量是由一个或多个单位组成的字符串,比如
3M12G9M表示3M + 12G + 9M。需要对字符串进行解析并计算总的容量。 - 
字符串处理:为了处理多个单位的情况,可以通过正则表达式或逐个字符扫描的方式提取数值和单位。
 
复杂度分析
- 
时间复杂度:
calc函数需要对每个磁盘字符串进行一次解析,时间复杂度为 O(L),其中 L 是每个磁盘容量字符串的长度。排序使用的是O(n log n)的时间复杂度,其中n是磁盘的数量。因此,总时间复杂度是O(n * L + n log n)。 - 
空间复杂度:主要空间消耗来自存储输入的磁盘字符串和排序过程中的临时存储,空间复杂度为
O(n),其中n是磁盘数量。 
代码实现
C++
#include <bits/stdc++.h>
using namespace std;
// 计算给定字符串的总容量,返回单位为M的数值
long long calc(string &s) {
    long long ans = 0;
    long long num = 0;
    for (const auto &c: s) {
        if (isdigit(c)) {
            num *= 10; 
            num += c - '0';  // 读取数字
        } else {
            switch (c) {
                case 'M': ans += num; break;  // 处理M单位
                case 'G': ans += num * 1024; break;  // 处理G单位
                case 'T': ans += num * 1024 * 1024; break;  // 处理T单位
            }
            num = 0;  // 重置num为0,准备下一个数字
        }
    }
    return ans;
}
int main() {
    int n;
    cin >> n;
    
    vector<string> disks(n);
    for (int i = 0; i < n; i++) {
        cin >> disks[i];  // 输入每块磁盘的容量字符串
    }
    // 稳定排序,根据磁盘容量的大小进行排序
    sort(disks.begin(), disks.end(), [](string a, string b) {
        return calc(a) < calc(b);
    });
    // 输出排序后的结果
    for (const auto &disk: disks) {
        cout << disk << endl;
    }
    return 0;
}
Python
import re
# 计算给定字符串的总容量,返回单位为M的数值
def calc(s):
    total = 0
    pattern = re.compile(r'(\d+)([MGT])')  # 匹配数字后跟单位M、G、T
    for match in pattern.findall(s):
        num = int(match[0])
        unit = match[1]
        if unit == 'M':
            total += num
        elif unit == 'G':
            total += num * 1024
        elif unit == 'T':
            total += num * 1024 * 1024
    
    return total
# 主函数
def main():
    n = int(input())  # 输入磁盘数量
    disks = [input().strip() for _ in range(n)]  # 输入每个磁盘的容量字符串
    # 稳定排序,根据磁盘容量大小排序
    disks.sort(key=lambda x: calc(x))
    # 输出排序后的磁盘容量
    for disk in disks:
        print(disk)
if __name__ == "__main__":
    main()
Java
import java.util.*;
import java.util.regex.*;
public class Main {
    // 计算给定字符串的总容量,返回单位为M的数值
    public static long calc(String s) {
        long total = 0;
        Pattern p = Pattern.compile("(\\d+)([MGT])");
        Matcher m = p.matcher(s);
        while (m.find()) {
            int num = Integer.parseInt(m.group(1));
            char unit = m.group(2).charAt(0);
            if (unit == 'M') {
                total += num;
            } else if (unit == 'G') {
                total += num * 1024;
            } else if (unit == 'T') {
                total += num * 1024 * 1024;
            }
        }
        return total;
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();  // 输入磁盘数量
        scanner.nextLine();  // 读取换行符
        List<String> disks = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            disks.add(scanner.nextLine().trim());  // 输入磁盘容量字符串
        }
        // 稳定排序,根据磁盘容量的大小排序
        disks.sort((a, b) -> Long.compare(calc(a), calc(b)));
        // 输出排序后的磁盘容量
        for (String disk : disks) {
            System.out.println(disk);
        }
    }
}
        题目描述
磁盘的容量单位常用的有 M,G,T 这三个等级,
它们之间的换算关系为 1T=1024G , 1G=1024M ,
现在给定 n 块磁盘的容量,请对它们按从小到大的顺序进行稳定排序,
例如给定 5 块盘的容量,1T,20M,3G,10G6T,3M12G9M
排序后的结果为 20M,3G,3M12G9M,1T,10G6T 。
注意单位可以重复出现,上述 3M12G9M 表示的容量即为 3M+12G+9M ,和 12M12G 相等。
输入描述
输入第一行包含一个整数 n(2<=n<=100),表示磁盘的个数,
接下的 n 行,每行一个字符串(长度大于 2 ,小于 30 ),
表示磁盘的容量,由一个或多个格式为 mv 的子串组成,
其中 m 表示容量大小, v 表示容量单位,例如 20M,1T,30G,10G6T,3M12G9M 。
磁盘容量 m 的范围为 1 到 1024 的正整数,
容量单位 v 的范围只包含题目中提到的 M,G,T 三种,换算关系如题目描述。
输出描述
输出 n 行,表示 n 块磁盘容量排序后的结果。
样例1
输入
3
1G
2G
1024M
输出
1G
1024M
2G
说明
1G 和 1024M 容量相等,稳定排序要求保留它们原来的相对位置,故 1G 在 1024M 之前。
样例2
输入
3
2G4M
3M2G
1T
输出
3M2G
2G4M
1T
说明
1T 的容量大于 2G4M ,2G4M 的容量大于 3M2G 。