此类输入一般只包含单个字符串,如
abc123
python
s = input()
java
Scanner sc = new Scanner(System.in);
String s = sc.nextLine(); // 读取一行字符串
cpp
String s;
cin >> s;
此类输入一般只包含单个数字,如
5
python
num = int(input())
java
Scanner sc = new Scanner(System.in);
int num = sc.nextInt(); // 读取一个整数
cpp
int num;
cin >> num;
此类输入一般会先在第一行输入长度n
,再在第二行输入长度为n
的数组。
数组可能会用空格隔开,如
3
aaa bbb ccc
python
# 输入数组长度n,需要转化为int类型
n = int(input())
# 使用字符串的split()方法进行分割,默认为根据空格进行分割
lst = input().split()
# ["aaa", "bbb", "ccc"]
java
Scanner sc = new Scanner(System.in);
String[] lst = sc.nextLine().split(" "); // 用空格分割字符串
cpp
int n;
cin >> n; // 读取数组长度n
string input;
cin.ignore(); // 忽略前一个输入的换行符
getline(cin, input); // 读取整行输入
vector<string> lst;
stringstream ss(input); // 使用字符串流进行处理
string token;
while (getline(ss, token, ' ')) { // 使用空格分割字符串
lst.push_back(token);
}
数组可能会用逗号隔开,如
3
aaa,bbb,ccc
python
# 输入数组长度n,需要转化为int类型
n = int(input())
# 使用字符串的split()方法进行分割,参数入字符串",",表示根据逗号","进行分割
lst = input().split(",")
# ["aaa", "bbb", "ccc"]
java
Scanner sc = new Scanner(System.in);
String[] lst = sc.nextLine().split(","); // 用逗号分割字符串
cpp
int n;
cin >> n; // 读取数组长度n
string input;
cin.ignore(); // 忽略前一个输入的换行符
getline(cin, input); // 读取整行输入
vector<string> lst;
stringstream ss(input); // 使用字符串流进行处理
string token;
while (getline(ss, token, ',')) { // 使用逗号分割字符串
lst.push_back(token);
}
此类输入一般会先在第一行输入长度n
,再在第二行输入长度为n
的数组。
数组可能会用空格隔开,如
3
0 1 2
python
# 输入数组长度n,需要转化为int类型
n = int(input())
# input().split()会得到["0", "1", "2"]
# 用map()可以把["0", "1", "2"]中的每一个元素映射地使用int(),
# 结果就可以得到[0, 1, 2]
nums = list(map(int, input().split()))
java
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
或者(可以处理数组长度n
未知的输入)
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
List<Integer> nums = new ArrayList<>();
while (scanner.hasNextInt()) {
nums.add(scanner.nextInt());
}
cpp
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
或者(可以用于处理数组长度n
未知的输入)
int n;
cin >> n;
vector<int> nums;
while (cin >> num) {
nums.push_back(num);
}
数组可能会用逗号隔开,如
3
0,1,2
python
# 输入数组长度n,需要转化为int类型
n = int(input())
lst = list(map(int, input().split(",")))
java
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(); // Input array length
List<Integer> lst = new ArrayList<>();
scanner.nextLine(); // Move to the next line after reading the integer
String[] input = scanner.nextLine().split(",");
for (String num : input) {
lst.add(Integer.parseInt(num.trim()));
}
cpp
int n;
cin >> n;
string s;
cin >> s;
int curr = 0 ;
vector<int> arr;
for (char c: s) {
if (c != ',') {
curr = curr * 10 + c - '0';
}else {
arr.push_back(curr);
curr = 0;
}
}
arr.push_back(curr);
此类输入一般会先在第一行输入二维数组的行数n
和列数吗m
,再在接下来的n
行输入长度为m
的字符串或者数组。
字符串类型输入
5 4
aaaa
bbbb
bbcc
ddee
ffgg
python
# 输入二维数组的行数n和列数m,需要转化为int类型
n, m = map(int, input().split())
grid = list()
for i in range(n): # 遍历n行
grid.append(list(input()))
# 或者grid.append(input())
java
Scanner sc = new Scanner(System.in);
int height =sc.nextInt();
int width = sc.nextInt();
char map[][] =new char [height][width];
for(int i=0;i<heiht;i++){
map[i] =sc.nextLine().toCharArray();
}
cpp
int n, m;
cin >> n >> m;
vector<string> maze(n);
for (int i = 0; i < n; i++) {
cin >> maze[i];
}
数字类型输入
5 4
0 0 0 0
0 0 0 1
1 1 1 2
2 2 2 3
3 3 4 4
python
# 输入二维数组的行数n和列数m,需要转化为int类型
n, m = map(int, input().split(","))
grid = list()
for i in range(n): # 遍历n行
grid.append(list(map(int, input().split())))
java
Scanner sc = new Scanner(System.in);
int height =sc.nextInt();
int width = sc.nextInt();
int map[][] =new int [height][width];
for(int i=0;i<heiht;i++){
for(int j=0;i<width;j++){
map[i][j] =sc.nextInt();
}
}
cpp
int n, m;
cin >> n >> m;
vector<vector<int>> maze(n, vector<int>(m, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> maze[i][j];
}
}
这种输入一般会告诉你树/图结构的边数,然后输入节点编号之间的连接关系。一般而言,题目会告知输入每一条边时,哪个节点是父/子节点。如
# 有向图一共有2条边
# 每条边输入时
# 第一个元素是父节点,第二个元素是子节点
2
1 2
1 3
# 一棵形如
# 1
# / \
# 2 3
# 的树形结构
一般采用构建邻接表的形式来表示一个图,而邻接表可以用哈希表很方便地表示。
python
# 导入defaultdict模块,用哈希表来表示图的邻接表
from collections import defaultdict
# 输入边的个数,如果是树形结构,则边的个数等于节点个数-1
edge_num = int(input())
# 初始化邻接表,key为节点编号,value为其子节点或邻接节点所构成的列表
neighbor_dic = defaultdict(list)
# 遍历每一条边的情况
for _ in range(edge_num):
# 获得具有邻接关系的两个节点
parent, child = map(int, input().split())
# 将child作为parent的子节点,加入邻接表neighbor_dic中
neighbor_dic[parent].append(child)
# 如果题目是无向图,还需要加上以下语句
# neighbor_dic[child].append(parent)
java
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(); // Number of nodes
int m = scanner.nextInt(); // Number of edges
List<List<Integer>> g = new ArrayList<>(n + 1);
for (int i = 0; i <= n; i++) {
g.add(new ArrayList<>());
}
for (int i = 1; i <= m; i++) {
int u = scanner.nextInt();
int v = scanner.nextInt();
// Directed graph
g.get(u).add(v);
cpp
int n, m;
//节点数n和边数m
cin >> n >> m;
vector<vector<int> > g(n + 1);//邻接表
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
//有向图
g[u].push_back(v);
}
这种输入一般存在多组输入的情况,以某一标识符作为停止输入的标志。如输入若干行,以END
作为终止输入的标志
0
1
2
END
这种输入一般需要结合while
循环进行。
python
# 输入第1行的情况
n = input()
# 当n不为停止标志"END"的时候,进行计算
while n != "END":
'''
中间一般会包含若干代码,对输入的n进行计算或处理
'''
n = input()
java
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String str = scanner.next();
if (str.equals("END")) {
break;
}
// do something
}
cpp
string str;
while(cin >> str) {
if (str == "END") {
break;
}
//do something
}
输入若干行,但不知道输入次数。如
0
1
2
3
python
# try-except异常处理语句可以用来解决输入次数未知的问题
# 当try中的语句块没有出现错误、可以正常运行时时,执行try中的语句块,否则执行except下的语句块
while(True):
try:
n = int(input())
# do something
except:
break
java
Scanner scanner = new Scanner(System.in);
while (true) {
try {
int n = scanner.nextInt();
// do something
} catch (Exception e) {
break;
}
}
cpp
int n;
//cpp while cin读取到文件尾
while(cin >> n) {
//do something
}
一般来说直接print()
即可。不可以在主函数中用return
代替print()
。
python
print(ans)
java
System.out.println(ans);
cpp
cout << ans << endl;
两者的区别可以通过以下表格看出些许端倪。
核心代码模式 | ACM模式 | |
---|---|---|
出现场景 | LeetCode、HackerRank | 牛客,大厂/OD笔试,欧弟OJ,自己的IDE |
输入 | 用函数传参的方式传入参数传入的变量一般无需再做数据类型的转换 | 用input() 的方式输入参数需要用split() 或map() 等函数得到合适的****数据类型 |
输出 | 使用return 返回答案在代码中任意位置均可以return | 使用print() 输出答案在代码最后进行print() |
如果要在自己的IDE上使用这两种不同的模式进行调试,以LC150. 逆波兰表达式为例,可以参考以下两种不同的代码。
# 题目:LC150. 逆波兰表达式
# 作者:许老师-闭着眼睛学数理化
# 模式:核心代码模式
'''
以下内容,在LeetCode中是需要补充完成的部分
'''
#创建类
class Solution:
# 实现Solution类的核心方法evalRPN(self, tokens)
def evalRPN(self, tokens):
stack = list() # 初始化一个栈stack
for ch in tokens: # 遍历tokens列表中的所有元素ch
if ch == "+": # 当ch为"+"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相加,再压入栈中
n2 = stack.pop()
stack.append(n2+n1)
elif ch == "-": # 当ch为"-"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相减,再压入栈中
n2 = stack.pop()
stack.append(n2-n1)
elif ch == "*": # 当ch为"*"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相乘,再压入栈中
n2 = stack.pop()
stack.append(n2*n1)
elif ch == '/': # 当ch为"/"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相除,再压入栈中
n2 = stack.pop()
stack.append(int(n2/n1)) # 注意要使用int(n2/n2)令结果整除
else:
stack.append(int(ch)) # 当ch为数字,将其压入栈中
return stack[0] # 运算到最后,栈中只剩下一个数字,即为答案
'''
以下内容,在LeetCode中是在系统后台自动调用的
'''
# 创建输入的tokens
tokens = input().split()
# 创建Solution类的一个实例对象sol
sol = Solution()
# 调用对象sol中的方法,将tokens作为参数传入evalRPN()方法中
ans = sol.evalRPN(tokens)
# 输出答案
print(ans)
# 题目:LC150. 逆波兰表达式
# 作者:许老师-闭着眼睛学数理化
# 模式:ACM模式
'''
以下内容,在牛客或OD考试中均要自己实现
'''
# 创建输入的tokens
tokens = input().split()
stack = list() # 初始化一个栈stack
for ch in tokens: # 遍历tokens列表中的所有元素ch
if ch == "+": # 当ch为"+"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相加,再压入栈中
n2 = stack.pop()
stack.append(n2+n1)
elif ch == "-": # 当ch为"-"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相减,再压入栈中
n2 = stack.pop()
stack.append(n2-n1)
elif ch == "*": # 当ch为"*"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相乘,再压入栈中
n2 = stack.pop()
stack.append(n2*n1)
elif ch == '/': # 当ch为"/"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相除,再压入栈中
n2 = stack.pop()
stack.append(int(n2/n1)) # 注意要使用int(n2/n2)令结果整除
else:
stack.append(int(ch)) # 当ch为数字,将其压入栈中
# 运算到最后,栈中只剩下一个数字,即为答案
print(stack[0])
你也可以将主要的算法逻辑封装一个函数,再在主体部分中调用。这样的写法更加贴近核心代码模式,也体现了程序设计的封装思想。
# 题目:LC150. 逆波兰表达式
# 作者:许老师-闭着眼睛学数理化
# 模式:ACM模式
'''
以下内容,在牛客或OD考试中均要自己实现
'''
# 定义函数evalRPN(),在主体部分中调用
def evalRPN(tokens):
stack = list() # 初始化一个栈stack
for ch in tokens: # 遍历tokens列表中的所有元素ch
if ch == "+": # 当ch为"+"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相加,再压入栈中
n2 = stack.pop()
stack.append(n2+n1)
elif ch == "-": # 当ch为"-"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相减,再压入栈中
n2 = stack.pop()
stack.append(n2-n1)
elif ch == "*": # 当ch为"*"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相乘,再压入栈中
n2 = stack.pop()
stack.append(n2*n1)
elif ch == '/': # 当ch为"/"号
n1 = stack.pop() # 将stack中最后两个元素弹出后相除,再压入栈中
n2 = stack.pop()
stack.append(int(n2/n1)) # 注意要使用int(n2/n2)令结果整除
else:
stack.append(int(ch)) # 当ch为数字,将其压入栈中
# 运算到最后,栈中只剩下一个数字,即为答案,需要return ans
return stack[0]
# 创建输入的tokens
tokens = input().split()
# 将tokens作为参数传入evalRPN()函数中,并返回ans
ans = evalRPN(tokens)
# 输出ans变量
print(ans)
大家不用过于纠结核心代码模式和ACM模式的区别,我们的学习重点主要还是算法和逻辑层面。
华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁
可上全网独家的欧弟OJ系统练习华子OD、大厂真题
可查看链接 大厂真题汇总 & OD真题汇总(持续更新)
绿色聊天软件戳 od1336
了解更多