一、问题描述
题目描述
给定一个非空字符串 S
,其被 N
个‘-’分隔成 N+1
的子串,给定正整数 K
,要求除第一个子串外,其余的串每 K
个用‘-’分隔,并将小写字母转换为大写。
输入描述
正整数 K
和‘-’分割的字符串,如:
2
25G3C-abc-d
输出描述
转换后的字符串
用例
用例 1
输入:
4
5F3Z-2e-9-w
输出:
5F3Z-2E9W
说明:
字符串 S
被分成了两个部分,每部分 4 个字符;
注意,两个额外的破折号需要删掉。
用例 2
输入:
2
2-5g-3-J
输出:
2-5G-3J
说明:
字符串 S
被分成了 3 个部分,按照前面的规则描述,第一部分的字符可以少于给定的数量,其余部分皆为 2 个字符。
解题思路
-
读取输入:
- 读取正整数
K
。 - 读取字符串
S
。
- 读取正整数
-
分割字符串:
- 使用
split('-')
方法将字符串S
按‘-’分割成子串数组。
- 使用
-
处理第一个子串:
- 第一个子串保持不变,但需要转换为大写。
-
处理其余子串:
- 将其余子串拼接成一个字符串。
- 将拼接后的字符串转换为大写。
- 每
K
个字符插入一个‘-’。
-
拼接结果:
- 将处理后的第一个子串和其余部分拼接成最终的字符串。
详细步骤
-
读取输入:
- 从标准输入读取正整数
K
。 - 从标准输入读取字符串
S
。
- 从标准输入读取正整数
-
分割字符串:
- 使用
split('-')
方法将字符串S
按‘-’分割成子串数组parts
。
- 使用
-
处理第一个子串:
- 将第一个子串
parts[0]
转换为大写。
- 将第一个子串
-
处理其余子串:
- 将
parts
从第二个子串开始拼接成一个字符串rest
。 - 将
rest
转换为大写。 - 每
K
个字符插入一个‘-’,使用match
方法和正则表达式实现。
- 将
-
拼接结果:
- 将处理后的第一个子串和其余部分拼接成最终的字符串。
-
输出结果:
- 输出拼接后的字符串。
用例解释
用例 1
- 输入:
K = 4
S = 5F3Z-2e-9-w
- 输出:
5F3Z-2E9W
解释:
- 第一个子串
5F3Z
保持不变。 - 其余子串
2e-9-w
拼接成2e9w
,转换为大写2E9W
。 - 每 4 个字符插入一个‘-’,得到
2E9W
。 - 最终结果为
5F3Z-2E9W
。
用例 2
- 输入:
K = 2
S = 2-5g-3-J
- 输出:
2-5G-3J
解释:
- 第一个子串
2
保持不变。 - 其余子串
5g-3-J
拼接成5g3J
,转换为大写5G3J
。 - 每 2 个字符插入一个‘-’,得到
5G-3J
。 - 最终结果为
2-5G-3J
。
通过上述步骤,我们可以高效地处理字符串,确保结果符合要求。这种方法的时间复杂度主要由字符串操作决定,为 O(n)
,其中 n
是字符串的长度。
二、JavaScript算法源码
以下是 JavaScript 代码的详细中文注释和逻辑讲解:
JavaScript 代码
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline"); // 引入 readline 模块,用于读取控制台输入
// 创建 readline 接口
const rl = readline.createInterface({
input: process.stdin, // 输入流为标准输入
output: process.stdout, // 输出流为标准输出
});
// 存储输入行的数组
const lines = [];
// 监听输入事件
rl.on("line", (line) => {
lines.push(line); // 将输入的行存入数组
// 当输入行数为 2 时,处理输入
if (lines.length === 2) {
const k = parseInt(lines[0]); // 解析第一个输入为整数 k
const s = lines[1]; // 获取第二个输入字符串 s
console.log(getResult(s, k)); // 调用 getResult 函数并输出结果
lines.length = 0; // 清空输入行数组
}
});
// 处理逻辑的函数
function getResult(s, k) {
// 将字符串 s 按 "-" 分割成数组
const sArr = s.split("-");
// 获取第一个部分
const first = sArr[0];
// 如果只有一个部分,直接返回
if (sArr.length == 1) return first;
// 将剩余部分拼接成一个字符串,并转换为大写
const tmp = sArr.slice(1).join("").toUpperCase().split("");
// 每隔 k 个字符插入一个 "-"
for (let i = 0; i < tmp.length; i++) {
if (i % k == 0) tmp[i] = "-" + tmp[i];
}
// 返回最终结果
return first + tmp.join("");
}
代码逻辑讲解
1. 引入模块
const readline = require("readline");
:引入readline
模块,用于读取控制台输入。
2. 创建 readline 接口
rl = readline.createInterface({ input: process.stdin, output: process.stdout });
:- 创建一个
readline
接口,用于从标准输入读取数据,并输出到标准输出。
- 创建一个
3. 存储输入行
const lines = [];
:定义一个数组lines
,用于存储用户输入的行。
4. 监听输入事件
rl.on("line", (line) => { ... });
:监听用户输入事件。- 每次用户输入一行内容时,将其存入
lines
数组。 - 当
lines
数组的长度为 2 时,表示用户已经输入了两行内容,开始处理输入。
- 每次用户输入一行内容时,将其存入
5. 处理输入
const k = parseInt(lines[0]);
:将第一行输入解析为整数k
。const s = lines[1];
:获取第二行输入字符串s
。console.log(getResult(s, k));
:调用getResult
函数处理输入,并输出结果。lines.length = 0;
:清空lines
数组,以便接收下一次输入。
6. 处理逻辑的函数
function getResult(s, k) { ... }
:定义处理逻辑的函数。- 步骤 1:将字符串
s
按"-"
分割成数组sArr
。- 例如,输入
"2-5g-3-J"
,分割后得到["2", "5g", "3", "J"]
。
- 例如,输入
- 步骤 2:获取第一个部分
first
。- 例如,
first = "2"
。
- 例如,
- 步骤 3:如果只有一个部分,直接返回
first
。- 例如,输入
"2"
,直接返回"2"
。
- 例如,输入
- 步骤 4:将剩余部分拼接成一个字符串,并转换为大写。
- 例如,剩余部分为
["5g", "3", "J"]
,拼接后得到"5g3J"
,转换为大写后得到"5G3J"
。
- 例如,剩余部分为
- 步骤 5:每隔
k
个字符插入一个"-"
。- 例如,
k = 2
,字符串为"5G3J"
:- 在第 0 个字符前插入
"-"
,得到"-5G3J"
。 - 在第 2 个字符前插入
"-"
,得到"-5G-3J"
。
- 在第 0 个字符前插入
- 例如,
- 步骤 6:返回最终结果。
- 例如,
first = "2"
,拼接后得到"2-5G-3J"
。
- 例如,
- 步骤 1:将字符串
代码细节解析
1. 输入处理
- 使用
readline
模块读取用户输入的两行内容。 - 第一行解析为整数
k
,第二行作为字符串s
。
2. 字符串分割
- 使用
split("-")
将字符串s
按"-"
分割成数组sArr
。
3. 处理剩余部分
- 使用
slice(1)
获取剩余部分,并拼接成一个字符串。 - 使用
toUpperCase()
将字符串转换为大写。
4. 插入分隔符
- 使用
for
循环遍历字符串,每隔k
个字符插入一个"-"
。
5. 返回结果
- 将第一个部分
first
和插入分隔符后的字符串拼接,返回最终结果。
示例运行
输入
2
2-5g-3-J
处理步骤
- 将字符串
"2-5g-3-J"
按"-"
分割成数组:
[
[“2”, “5g”, “3”, “J”]
] - 获取第一个部分
first = "2"
。 - 将剩余部分拼接成一个字符串并转换为大写:
[
“5G3J”
] - 每隔
k = 2
个字符插入一个"-"
:- 在第 0 个字符前插入
"-"
,得到"-5G3J"
。 - 在第 2 个字符前插入
"-"
,得到"-5G-3J"
。
- 在第 0 个字符前插入
- 返回最终结果:
[
“2-5G-3J”
]
输出
2-5G-3J
总结
- 功能:将输入的字符串按规则格式化,每隔
k
个字符插入一个"-"
。 - 核心逻辑:
- 按
"-"
分割字符串。 - 将剩余部分拼接并转换为大写。
- 每隔
k
个字符插入"-"
。
- 按
- 适用场景:需要格式化字符串的场景,例如生成特定格式的编号或代码。
- 注意事项:
- 输入字符串可能包含小写字母,需要转换为大写。
- 如果输入字符串只有一个部分,直接返回该部分。
如果有其他问题,欢迎随时提问!
三、Java算法源码
以下是 Java 代码的详细中文注释和逻辑讲解:
Java 代码
import java.util.Scanner; // 引入 Scanner 类,用于读取控制台输入
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); // 创建 Scanner 对象,用于读取输入
int k = sc.nextInt(); // 读取整数 k
String str = sc.next(); // 读取字符串 str
System.out.println(getResult(k, str)); // 调用 getResult 方法并输出结果
}
// 处理逻辑的方法
public static String getResult(int k, String str) {
// 将字符串 str 按 "-" 分割成数组
String[] sArr = str.split("-");
// 获取第一个部分
String first = sArr[0];
// 如果只有一个部分,直接返回
if (sArr.length == 1) return first;
// 使用 StringBuilder 拼接剩余部分
StringBuilder sb = new StringBuilder();
for (int i = 1; i < sArr.length; i++) {
sb.append(sArr[i]); // 将剩余部分拼接到 StringBuilder 中
}
// 将拼接后的字符串转换为大写,并拆分为字符数组
String[] tmp = sb.toString().toUpperCase().split("");
// 每隔 k 个字符插入一个 "-"
for (int i = 0; i < tmp.length; i++) {
if (i % k == 0) tmp[i] = "-" + tmp[i]; // 在第 i 个字符前插入 "-"
}
// 返回最终结果
return first + String.join("", tmp);
}
}
代码逻辑讲解
1. 引入 Scanner 类
import java.util.Scanner;
:引入Scanner
类,用于读取控制台输入。
2. 主方法
public static void main(String[] args) { ... }
:程序入口。- 创建
Scanner
对象sc
,用于读取用户输入。 - 读取整数
k
和字符串str
。 - 调用
getResult
方法处理输入,并输出结果。
- 创建
3. 处理逻辑的方法
public static String getResult(int k, String str) { ... }
:定义处理逻辑的方法。- 步骤 1:将字符串
str
按"-"
分割成数组sArr
。- 例如,输入
"2-5g-3-J"
,分割后得到["2", "5g", "3", "J"]
。
- 例如,输入
- 步骤 2:获取第一个部分
first
。- 例如,
first = "2"
。
- 例如,
- 步骤 3:如果只有一个部分,直接返回
first
。- 例如,输入
"2"
,直接返回"2"
。
- 例如,输入
- 步骤 4:使用
StringBuilder
拼接剩余部分。- 例如,剩余部分为
["5g", "3", "J"]
,拼接后得到"5g3J"
。
- 例如,剩余部分为
- 步骤 5:将拼接后的字符串转换为大写,并拆分为字符数组。
- 例如,
"5g3J"
转换为大写后得到"5G3J"
,拆分为["5", "G", "3", "J"]
。
- 例如,
- 步骤 6:每隔
k
个字符插入一个"-"
。- 例如,
k = 2
,字符数组为["5", "G", "3", "J"]
:- 在第 0 个字符前插入
"-"
,得到["-5", "G", "3", "J"]
。 - 在第 2 个字符前插入
"-"
,得到["-5", "G", "-3", "J"]
。
- 在第 0 个字符前插入
- 例如,
- 步骤 7:返回最终结果。
- 例如,
first = "2"
,拼接后得到"2-5G-3J"
。
- 例如,
- 步骤 1:将字符串
代码细节解析
1. 输入处理
- 使用
Scanner
类读取用户输入的两个值:int k = sc.nextInt();
:读取整数k
。String str = sc.next();
:读取字符串str
。
2. 字符串分割
- 使用
split("-")
将字符串str
按"-"
分割成数组sArr
。
3. 处理剩余部分
- 使用
StringBuilder
拼接剩余部分,避免频繁创建字符串对象。 - 使用
toString()
将StringBuilder
转换为字符串。 - 使用
toUpperCase()
将字符串转换为大写。 - 使用
split("")
将字符串拆分为字符数组。
4. 插入分隔符
- 使用
for
循环遍历字符数组,每隔k
个字符插入一个"-"
。
5. 返回结果
- 使用
String.join("", tmp)
将字符数组拼接成字符串。 - 将第一个部分
first
和插入分隔符后的字符串拼接,返回最终结果。
示例运行
输入
2
2-5g-3-J
处理步骤
- 将字符串
"2-5g-3-J"
按"-"
分割成数组:
[
[“2”, “5g”, “3”, “J”]
] - 获取第一个部分
first = "2"
。 - 将剩余部分拼接成一个字符串并转换为大写:
[
“5G3J”
] - 每隔
k = 2
个字符插入一个"-"
:- 在第 0 个字符前插入
"-"
,得到["-5", "G", "3", "J"]
。 - 在第 2 个字符前插入
"-"
,得到["-5", "G", "-3", "J"]
。
- 在第 0 个字符前插入
- 返回最终结果:
[
“2-5G-3J”
]
输出
2-5G-3J
总结
- 功能:将输入的字符串按规则格式化,每隔
k
个字符插入一个"-"
。 - 核心逻辑:
- 按
"-"
分割字符串。 - 将剩余部分拼接并转换为大写。
- 每隔
k
个字符插入"-"
。
- 按
- 适用场景:需要格式化字符串的场景,例如生成特定格式的编号或代码。
- 注意事项:
- 输入字符串可能包含小写字母,需要转换为大写。
- 如果输入字符串只有一个部分,直接返回该部分。
如果有其他问题,欢迎随时提问!
四、Python算法源码
以下是 Python 代码的详细中文注释和逻辑讲解:
Python 代码
# 输入获取
k = int(input()) # 读取整数 k
s = input() # 读取字符串 s
# 算法入口
def getResult():
# 将字符串 s 按 "-" 分割成数组
sArr = s.split("-")
# 获取第一个部分
first = sArr[0]
# 如果只有一个部分,直接返回
if len(sArr) == 1:
return first
# 将剩余部分拼接成一个字符串,并转换为大写
tmp = list("".join(sArr[1:]).upper())
# 每隔 k 个字符插入一个 "-"
for i in range(len(tmp)):
if i % k == 0:
tmp[i] = "-" + tmp[i]
# 返回最终结果
return first + "".join(tmp)
# 算法调用
print(getResult())
代码逻辑讲解
1. 输入获取
k = int(input())
:读取用户输入的整数k
。s = input()
:读取用户输入的字符串s
。
2. 算法入口
def getResult():
:定义处理逻辑的函数。- 步骤 1:将字符串
s
按"-"
分割成数组sArr
。- 例如,输入
"2-5g-3-J"
,分割后得到["2", "5g", "3", "J"]
。
- 例如,输入
- 步骤 2:获取第一个部分
first
。- 例如,
first = "2"
。
- 例如,
- 步骤 3:如果只有一个部分,直接返回
first
。- 例如,输入
"2"
,直接返回"2"
。
- 例如,输入
- 步骤 4:将剩余部分拼接成一个字符串,并转换为大写。
- 例如,剩余部分为
["5g", "3", "J"]
,拼接后得到"5g3J"
,转换为大写后得到"5G3J"
。
- 例如,剩余部分为
- 步骤 5:每隔
k
个字符插入一个"-"
。- 例如,
k = 2
,字符数组为["5", "G", "3", "J"]
:- 在第 0 个字符前插入
"-"
,得到["-5", "G", "3", "J"]
。 - 在第 2 个字符前插入
"-"
,得到["-5", "G", "-3", "J"]
。
- 在第 0 个字符前插入
- 例如,
- 步骤 6:返回最终结果。
- 例如,
first = "2"
,拼接后得到"2-5G-3J"
。
- 例如,
- 步骤 1:将字符串
3. 算法调用
print(getResult())
:调用getResult
函数并输出结果。
代码细节解析
1. 输入处理
- 使用
input()
函数读取用户输入的两个值:k = int(input())
:读取整数k
。s = input()
:读取字符串s
。
2. 字符串分割
- 使用
split("-")
将字符串s
按"-"
分割成数组sArr
。
3. 处理剩余部分
- 使用
"".join(sArr[1:])
将剩余部分拼接成一个字符串。 - 使用
upper()
将字符串转换为大写。 - 使用
list()
将字符串拆分为字符数组。
4. 插入分隔符
- 使用
for
循环遍历字符数组,每隔k
个字符插入一个"-"
。
5. 返回结果
- 使用
"".join(tmp)
将字符数组拼接成字符串。 - 将第一个部分
first
和插入分隔符后的字符串拼接,返回最终结果。
示例运行
输入
2
2-5g-3-J
处理步骤
- 将字符串
"2-5g-3-J"
按"-"
分割成数组:
[
[“2”, “5g”, “3”, “J”]
] - 获取第一个部分
first = "2"
。 - 将剩余部分拼接成一个字符串并转换为大写:
[
“5G3J”
] - 每隔
k = 2
个字符插入一个"-"
:- 在第 0 个字符前插入
"-"
,得到["-5", "G", "3", "J"]
。 - 在第 2 个字符前插入
"-"
,得到["-5", "G", "-3", "J"]
。
- 在第 0 个字符前插入
- 返回最终结果:
[
“2-5G-3J”
]
输出
2-5G-3J
总结
- 功能:将输入的字符串按规则格式化,每隔
k
个字符插入一个"-"
。 - 核心逻辑:
- 按
"-"
分割字符串。 - 将剩余部分拼接并转换为大写。
- 每隔
k
个字符插入"-"
。
- 按
- 适用场景:需要格式化字符串的场景,例如生成特定格式的编号或代码。
- 注意事项:
- 输入字符串可能包含小写字母,需要转换为大写。
- 如果输入字符串只有一个部分,直接返回该部分。
如果有其他问题,欢迎随时提问!
五、C/C++算法源码:
以下是 C++ 代码 和 C 语言代码 的实现,并附带详细的中文注释和逻辑讲解。
C++ 代码
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// 算法入口
string getResult(int k, string s) {
// 将字符串 s 按 "-" 分割成数组
vector<string> sArr;
size_t pos = 0;
while ((pos = s.find("-")) != string::npos) {
sArr.push_back(s.substr(0, pos)); // 将分割的部分加入数组
s.erase(0, pos + 1); // 删除已处理的部分
}
sArr.push_back(s); // 加入最后一部分
// 获取第一个部分
string first = sArr[0];
// 如果只有一个部分,直接返回
if (sArr.size() == 1) {
return first;
}
// 将剩余部分拼接成一个字符串,并转换为大写
string remaining;
for (size_t i = 1; i < sArr.size(); i++) {
remaining += sArr[i];
}
transform(remaining.begin(), remaining.end(), remaining.begin(), ::toupper); // 转换为大写
// 每隔 k 个字符插入一个 "-"
string result = first;
for (size_t i = 0; i < remaining.length(); i++) {
if (i % k == 0) {
result += "-"; // 插入分隔符
}
result += remaining[i];
}
return result;
}
int main() {
// 输入获取
int k;
string s;
cin >> k >> s;
// 算法调用
cout << getResult(k, s) << endl;
return 0;
}
C 语言代码
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// 算法入口
char* getResult(int k, char* s) {
// 将字符串 s 按 "-" 分割成数组
char* sArr[100]; // 假设最多分割 100 部分
int count = 0;
char* token = strtok(s, "-");
while (token != NULL) {
sArr[count++] = token; // 将分割的部分加入数组
token = strtok(NULL, "-");
}
// 获取第一个部分
char* first = sArr[0];
// 如果只有一个部分,直接返回
if (count == 1) {
return first;
}
// 将剩余部分拼接成一个字符串,并转换为大写
char remaining[1000] = ""; // 假设剩余部分长度不超过 1000
for (int i = 1; i < count; i++) {
strcat(remaining, sArr[i]);
}
for (int i = 0; remaining[i]; i++) {
remaining[i] = toupper(remaining[i]); // 转换为大写
}
// 每隔 k 个字符插入一个 "-"
char result[1000] = ""; // 假设结果长度不超过 1000
strcat(result, first); // 加入第一个部分
for (int i = 0; i < strlen(remaining); i++) {
if (i % k == 0) {
strcat(result, "-"); // 插入分隔符
}
result[strlen(result)] = remaining[i]; // 加入字符
}
return strdup(result); // 返回动态分配的结果
}
int main() {
// 输入获取
int k;
char s[1000]; // 假设输入字符串长度不超过 1000
scanf("%d %s", &k, s);
// 算法调用
char* result = getResult(k, s);
printf("%s\n", result);
// 释放动态分配的内存
free(result);
return 0;
}
代码逻辑讲解
1. 输入获取
- C++:
- 使用
cin
读取整数k
和字符串s
。
- 使用
- C:
- 使用
scanf
读取整数k
和字符串s
。
- 使用
2. 字符串分割
- C++:
- 使用
find
和substr
方法按"-"
分割字符串,并将结果存入vector<string>
。
- 使用
- C:
- 使用
strtok
函数按"-"
分割字符串,并将结果存入字符指针数组sArr
。
- 使用
3. 处理剩余部分
- C++:
- 使用
transform
函数将剩余部分转换为大写。
- 使用
- C:
- 使用
toupper
函数将剩余部分转换为大写。
- 使用
4. 插入分隔符
- C++:
- 使用
for
循环遍历剩余部分,每隔k
个字符插入一个"-"
。
- 使用
- C:
- 使用
for
循环遍历剩余部分,每隔k
个字符插入一个"-"
。
- 使用
5. 返回结果
- C++:
- 返回拼接后的字符串。
- C:
- 使用
strdup
动态分配内存并返回结果。
- 使用
示例运行
输入
2
2-5g-3-J
处理步骤
- 将字符串
"2-5g-3-J"
按"-"
分割成数组:
[
[“2”, “5g”, “3”, “J”]
] - 获取第一个部分
first = "2"
。 - 将剩余部分拼接成一个字符串并转换为大写:
[
“5G3J”
] - 每隔
k = 2
个字符插入一个"-"
:- 在第 0 个字符前插入
"-"
,得到["-5", "G", "3", "J"]
。 - 在第 2 个字符前插入
"-"
,得到["-5", "G", "-3", "J"]
。
- 在第 0 个字符前插入
- 返回最终结果:
[
“2-5G-3J”
]
输出
2-5G-3J
总结
- 功能:将输入的字符串按规则格式化,每隔
k
个字符插入一个"-"
。 - 核心逻辑:
- 按
"-"
分割字符串。 - 将剩余部分拼接并转换为大写。
- 每隔
k
个字符插入"-"
。
- 按
- 适用场景:需要格式化字符串的场景,例如生成特定格式的编号或代码。
- 注意事项:
- 输入字符串可能包含小写字母,需要转换为大写。
- 如果输入字符串只有一个部分,直接返回该部分。
如果有其他问题,欢迎随时提问!