专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
给定一个非空字符串 Q S,其被 N 个‘;’分隔成 N+1 个子串,给定正整数数组 K,要求除第一个子串外,其余的子串每 K 个字符组成新的子串,并‘-’分隔。
对于新组成的每一个子串,如果它含有的小写字母比大写字母多,则将这个子串的所有大写字母转换为小写 Q 字母;
反之,如果它含有的大写字母比小写字母多,则将这个子串的所有小写字母转换为大写字母;大小写字母的数量相等时,不做转换。
二、输入描述
输入为两行,第一行为参数 K,第二行为字符串 S。
三、输出描述
输出转换后的字符串。
四、测试用例
测试用例1:
1、输入
3
12abc-abCABc-4aB@
2、输出
12abc-abc-ABC-4aB-@
3、说明
子串为 12abc、abCABc、4aB@,第一个子串保留,
后面的子串每 3 个字符一组为 abC、ABC、4aB、@,
abC 中小写字母较多,转换为 abc,
ABC 中大写字母较多,转换为 ABC,
4aB 中大小写字母都为 1 个,不做转换,
@ 中没有字母,连起来即 12abc-abc-ABC-4aB-@
测试用例2:
1、输入
12
12abc-abCABc-4aB@
2、输出
12abc-abCABc4aB@
3、说明
子串为 12abc、abCABc、4aB@,第一个子串保留,
后面的子串每 12 个字符一组为 abCABc4aB@,
这个子串中大小写字母都为 4 个,不做转换,
连起来即 12abc-abCABc4aB@
五、解题思路
- 读取两个输入参数 K 和 S,其中 K 表示每个子串的长度,S 是要处理的字符串。
- 将字符串 S 按 ‘-’ 拆分成多个子串。保留第一个子串(one),然后将其余子串拼接成一个大字符串。
- 根据给定的长度 K,将拼接后的字符串重新划分成多个子串,使用 ‘-’ 作为分隔符。
- 对每个新划分的子串统计大写和小写字母的数量,并根据数量决定是否转换为全大写或全小写,或保持不变。
- 将转换后的子串重新拼接成一个完整的字符串,并输出最终结果。
六、Python算法源码
def transform_string(k, s):
"""
将字符串按照'-'分隔,对第一个子串之后的每个子串,按照K个字符进行分割并用'-'连接
根据大小写字母数量对每个新子串进行大小写转换
参数:
k: 分割字符的长度
s: 输入字符串
返回:
处理后的字符串
"""
# 按'-'分隔字符串
chunks = s.split('-')
result = [chunks[0]] # 结果从第一个子串开始
# 处理剩余的子串
for i in range(1, len(chunks)):
chunk = chunks[i]
# 对每个子串按K个字符进行分割
for j in range(0, len(chunk), k):
# 获取当前部分(最多K个字符)
part = chunk[j:min(j+k, len(chunk))]
# 统计大小写字母数量
uppercase_count = sum(1 for c in part if c.isupper())
lowercase_count = sum(1 for c in part if c.islower())
# 根据大小写字母数量应用转换规则
if lowercase_count > uppercase_count:
# 小写字母多,将所有大写字母转为小写
part = part.lower()
elif uppercase_count > lowercase_count:
# 大写字母多,将所有小写字母转为大写
part = part.upper()
# 大小写字母数量相等时,不做转换
result.append(part)
# 用'-'连接所有处理后的部分
return '-'.join(result)
# 读取输入
k = int(input())
s = input()
# 处理并输出结果
print(transform_string(k, s))
七、JavaScript算法源码
/**
* 将字符串按照'-'分隔,对第一个子串之后的每个子串,按照K个字符进行分割并用'-'连接
* 根据大小写字母数量对每个新子串进行大小写转换
*
* @param {number} k - 分割字符的长度
* @param {string} s - 输入字符串
* @returns {string} - 处理后的字符串
*/
function transformString(k, s) {
// 按'-'分隔字符串
const chunks = s.split('-');
const result = [chunks[0]]; // 结果从第一个子串开始
// 处理剩余的子串
for (let i = 1; i < chunks.length; i++) {
const chunk = chunks[i];
// 对每个子串按K个字符进行分割
for (let j = 0; j < chunk.length; j += k) {
// 获取当前部分(最多K个字符)
const part = chunk.substring(j, Math.min(j+k, chunk.length));
// 统计大小写字母数量
let uppercaseCount = 0;
let lowercaseCount = 0;
for (const c of part) {
if (c >= 'A' && c <= 'Z') {
uppercaseCount++;
} else if (c >= 'a' && c <= 'z') {
lowercaseCount++;
}
}
// 根据大小写字母数量应用转换规则
if (lowercaseCount > uppercaseCount) {
// 小写字母多,将所有大写字母转为小写
result.push(part.toLowerCase());
} else if (uppercaseCount > lowercaseCount) {
// 大写字母多,将所有小写字母转为大写
result.push(part.toUpperCase());
} else {
// 大小写字母数量相等时,不做转换
result.push(part);
}
}
}
// 用'-'连接所有处理后的部分
return result.join('-');
}
// 从命令行读取输入(在浏览器环境中可以使用prompt代替)
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let k;
let s;
let lineCount = 0;
rl.on('line', (line) => {
if (lineCount === 0) {
// 第一行是参数K
k = parseInt(line);
lineCount++;
} else {
// 第二行是字符串S
s = line;
// 输出结果
console.log(transformString(k, s));
rl.close();
}
});
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/**
* 将字符串按照'-'分隔,对第一个子串之后的每个子串,按照K个字符进行分割并用'-'连接
* 根据大小写字母数量对每个新子串进行大小写转换
*
* @param k: 分割字符的长度
* @param s: 输入字符串
* @return: 处理后的字符串,需要调用free释放内存
*/
char* transformString(int k, const char* s) {
// 创建输入字符串的副本,因为strtok会修改原字符串
char* s_copy = strdup(s);
// 分配结果字符串的内存(分配比原字符串长一倍的空间,足够容纳分割后可能增加的字符)
char* result = (char*)malloc(strlen(s) * 2 + 1);
result[0] = '\0'; // 初始化为空字符串
// 获取第一个子串
char* chunk = strtok(s_copy, "-");
strcpy(result, chunk); // 将第一个子串复制到结果中
// 处理剩余的子串
while ((chunk = strtok(NULL, "-")) != NULL) {
int chunkLength = strlen(chunk);
// 对每个子串按K个字符进行分割
for (int j = 0; j < chunkLength; j += k) {
strcat(result, "-"); // 添加连接符
// 获取当前部分(最多K个字符)
char part[1000]; // 假设部分不会超过1000个字符
int partLength = (j + k < chunkLength) ? k : chunkLength - j;
strncpy(part, chunk + j, partLength);
part[partLength] = '\0'; // 确保字符串以null结尾
// 统计大小写字母数量
int uppercaseCount = 0;
int lowercaseCount = 0;
for (int i = 0; i < partLength; i++) {
if (isupper(part[i])) {
uppercaseCount++;
} else if (islower(part[i])) {
lowercaseCount++;
}
}
// 根据大小写字母数量应用转换规则
if (lowercaseCount > uppercaseCount) {
// 小写字母多,将所有大写字母转为小写
for (int i = 0; i < partLength; i++) {
part[i] = tolower(part[i]);
}
} else if (uppercaseCount > lowercaseCount) {
// 大写字母多,将所有小写字母转为大写
for (int i = 0; i < partLength; i++) {
part[i] = toupper(part[i]);
}
}
// 大小写字母数量相等时,不做转换
strcat(result, part); // 将处理后的部分追加到结果中
}
}
free(s_copy); // 释放输入字符串的副本
return result;
}
int main() {
int k;
char s[1000]; // 假设输入字符串不会超过1000个字符
// 读取参数K
scanf("%d", &k);
getchar(); // 消耗换行符
// 读取字符串S
scanf("%[^\n]", s);
// 处理字符串并获取结果
char* transformedString = transformString(k, s);
// 输出结果
printf("%s\n", transformedString);
// 释放结果字符串的内存
free(transformedString);
return 0;
}
九、C++算法源码
#include <iostream>
#include <string>
#include <vector>
#include <cctype>
/**
* 将字符串按照'-'分隔,对第一个子串之后的每个子串,按照K个字符进行分割并用'-'连接
* 根据大小写字母数量对每个新子串进行大小写转换
*
* @param k: 分割字符的长度
* @param s: 输入字符串
* @return: 处理后的字符串
*/
std::string transformString(int k, const std::string& s) {
std::vector<std::string> chunks;
size_t pos = 0;
size_t found;
// 按'-'分隔字符串
while ((found = s.find('-', pos)) != std::string::npos) {
chunks.push_back(s.substr(pos, found - pos));
pos = found + 1;
}
chunks.push_back(s.substr(pos)); // 添加最后一个子串
// 结果从第一个子串开始
std::string result = chunks[0];
// 处理剩余的子串
for (size_t i = 1; i < chunks.size(); i++) {
const std::string& chunk = chunks[i];
// 对每个子串按K个字符进行分割
for (size_t j = 0; j < chunk.length(); j += k) {
// 获取当前部分(最多K个字符)
std::string part = chunk.substr(j, std::min(k, chunk.length() - j));
// 统计大小写字母数量
int uppercaseCount = 0;
int lowercaseCount = 0;
for (char c : part) {
if (std::isupper(c)) {
uppercaseCount++;
} else if (std::islower(c)) {
lowercaseCount++;
}
}
// 根据大小写字母数量应用转换规则
if (lowercaseCount > uppercaseCount) {
// 小写字母多,将所有大写字母转为小写
for (char& c : part) {
c = std::tolower(c);
}
} else if (uppercaseCount > lowercaseCount) {
// 大写字母多,将所有小写字母转为大写
for (char& c : part) {
c = std::toupper(c);
}
}
// 大小写字母数量相等时,不做转换
result += "-" + part;
}
}
return result;
}
int main() {
int k;
std::string s;
// 读取参数K
std::cin >> k;
std::cin.ignore(); // 消耗换行符
// 读取字符串S
std::getline(std::cin, s);
// 处理字符串并输出结果
std::cout << transformString(k, s) << std::endl;
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 B卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。