【Py/Java/C++三种语言】ACM模式输入输出总结【大厂笔试/OD机考】

文章目录

  • 输入字符串
  • 输入数字
  • 输入字符串数组
  • 输入数字型数组
  • 输入二维数组
  • 输入树或图结构
  • 输入次数若干,以某个标识符作为停止输入的标志
  • 输入次数未知(较少使用)
  • 输出
  • ACM模式与核心代码模式异同点总结
    • 核心代码模式
    • ACM模式
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

  1. 输入字符串

此类输入一般只包含单个字符串,如

abc123

python

s = input()

java

 Scanner sc = new Scanner(System.in);
 String s = sc.nextLine(); // 读取一行字符串

cpp

String s;
cin >> s;
  1. 输入数字

此类输入一般只包含单个数字,如

5

python

num = int(input())

java

 Scanner sc = new Scanner(System.in);
 int num = sc.nextInt(); // 读取一个整数

cpp

int num;
cin >> num;
  1. 输入字符串数组

此类输入一般会先在第一行输入长度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);
}
  1. 输入数字型数组

此类输入一般会先在第一行输入长度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);
  1. 输入二维数组

此类输入一般会先在第一行输入二维数组的行数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];
    }
}
  1. 输入树或图结构

这种输入一般会告诉你树/图结构的边数,然后输入节点编号之间的连接关系。一般而言,题目会告知输入每一条边时,哪个节点是父/子节点。如

# 有向图一共有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);
}
  1. 输入次数若干,以某个标识符作为停止输入的标志

这种输入一般存在多组输入的情况,以某一标识符作为停止输入的标志。如输入若干行,以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
}
  1. 输入次数未知(较少使用)

输入若干行,但不知道输入次数。如

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
}
  1. 输出

一般来说直接print()即可。不可以在主函数中用return代替print()

python

print(ans)

java

System.out.println(ans);

cpp

cout << ans << endl;
  1. ACM模式与核心代码模式异同点总结

两者的区别可以通过以下表格看出些许端倪。

核心代码模式 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)

ACM模式

# 题目: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算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

你可能感兴趣的:(算法刷题技巧,最新华为OD真题,大厂秋招真题,java,c++,python)