算法日志1:编程第一步,搞清读参数

news/2025/3/20 11:45:21/文章来源:https://www.cnblogs.com/duiwoeryan/p/18782754

前言

笔者上了几个月的班,昨天参加了一场笔试,感觉算法甚至编程语言的语法都忘光了(定义c语言数组想了十几分钟),于是痛定思痛,决心要把代码随想录的题刷一遍,系统的学一下算法。

笔者已经坚定决心,从本篇开始,不断记录自己的学习和思考过程(其实是大模型的思考过程!😃)


ACM 模式和 核心代码模式

ACM模式要自己处理系统输入输出, 核心代码模式是写一个核心函数



编程第一步,搞清读参数

C++ 的 cin/cout、C 的 scanf/printf、Python 的 sys.stdin/stdout 和 Shell 的标准输入输出(如管道和重定向)都是处理标准输入/输出(stdin/stdout)的工具,但它们在使用方式、性能、抽象层次和设计哲学上有显著区别和联系。以下是详细对比:


核心联系

  1. 统一的抽象概念
    所有工具都基于操作系统的标准输入/输出(stdin/stdout)概念,对应文件描述符 0(输入)和 1(输出)。

  2. 数据流方向一致
    均遵循“数据从 stdin 读取,处理后再写入 stdout”的流程。

  3. 可互相组合
    不同工具可通过管道(|)或重定向(<, >)协同工作。例如:

    # C++ 程序输出到 Python 脚本
    ./cpp_program | python3 script.py
    

主要区别

特性 C++ cin/cout C scanf/printf Python sys.stdin/stdout Shell 标准输入输出
语法风格 面向对象(运算符 >>/<< 函数式(格式字符串) 面向对象(文件对象方法) 命令式(管道 `
类型安全 是(自动类型推导) 否(需显式指定格式符,易出错) 是(动态类型) 无类型(纯文本流)
性能 较高(但默认同步 C 库,可能略慢) 最高(直接系统调用,无额外抽象) 较低(解释型语言,动态类型开销) 中等(依赖工具实现,如 grep/awk
缓冲机制 行缓冲(默认,可调整) 全缓冲(默认,可通过 fflush 控制) 全缓冲(可设置 flush=True 行缓冲(通常由工具自行管理)
错误处理 通过流状态(如 failbit)检查 通过返回值检查(如 scanf 返回成功数) 通过异常或返回值(如 read() 通过退出状态码($?
典型用途 类型安全的高性能 I/O 底层高效控制 快速开发和文本处理 文本流处理和工具组合
示例代码 cin >> x; cout << x; scanf("%d", &x); printf("%d", x); line = sys.stdin.readline() `cat file.txt

关键细节对比

1. 类型处理

  • C++cin >> x 根据 x 的类型自动解析输入(如 intstring),类型安全。
  • C:需显式指定格式符(如 %d%s),易因类型不匹配导致未定义行为。
  • Python:输入始终为字符串,需手动转换类型(如 int(input()))。
  • Shell:数据为纯文本流,需用工具(如 awk)解析类型。

2. 缓冲机制

  • C++cout 默认行缓冲(输出到终端时),但写入文件时为全缓冲;可通过 endlflush 强制刷新。
  • Cprintf 全缓冲,除非输出到终端(行缓冲);需手动调用 fflush(stdout)
  • Pythonprint 函数默认全缓冲,但可设置 flush=Truesys.stdout.write 需手动刷新。
  • Shell:管道中的工具通常行缓冲(如 grep),但某些工具(如 sed)可能全缓冲。

3. 性能考量

  • C/C++:适合处理大规模数据(如每秒百万级输入),但需避免频繁同步(如 sync_with_stdio(false))。
  • Python:处理大数据时性能较差,但可通过批量读取(如 sys.stdin.read())优化。
  • Shell:组合工具时性能取决于具体命令(如 awk 比纯 Shell 循环快)。

4. 错误处理

  • C++:通过 cin.fail() 检查输入错误,需手动清除状态(cin.clear())。
  • Cscanf 返回成功匹配的参数数量,需逐项检查。
  • Pythonsys.stdin.read() 可能抛出异常(如键盘中断),需 try/except 捕获。
  • Shell:通过 $? 获取上一个命令的退出状态(0 表示成功,非 0 表示失败)。

使用场景建议

  • 需要高性能和类型安全:优先选择 C++ cin/cout(关闭同步)或 C scanf/printf
  • 快速开发和文本处理:使用 Python sys.stdin 和字符串方法。
  • 组合现有工具处理文本流:Shell 管道和重定向(如 awk/sed)。
  • 混合语言协作:通过 stdin/stdout 跨语言传递数据(如 C++ 程序输出到 Python 脚本)。

示例:跨语言协作

# C 程序生成数据 → Python 处理 → Shell 过滤
./c_program | python3 script.py | grep "result"





c,c++, python输入输出函数的返回值详解:


C++ cincout

  1. cin >> var 的返回值

    • 类型istream&(输入流对象的引用)。

    • 行为:返回流对象本身,允许链式调用(如 cin >> a >> b;)。

    • 错误处理:可通过检查流状态判断是否成功:

      if (cin >> x) { /* 读取成功 */ }
      else { /* 失败(如类型不匹配或 EOF)*/ }
      
  2. cout << value 的返回值

    • 类型ostream&(输出流对象的引用)。
    • 行为:返回流对象本身,支持链式输出(如 cout << a << b;)。
    • 错误处理:通常不检查返回值,但可通过 cout.good() 检测流状态。

C 的 scanfprintf

  1. scanf 的返回值

    • 类型int

    • 行为:返回成功匹配并赋值的输入项数量。若遇到输入错误或 EOF,返回 EOF(通常是 -1)。

    • 示例

      int a, b;
      int result = scanf("%d %d", &a, &b);
      if (result == 2) { /* 成功读取两个整数 */ }
      else if (result == EOF) { /* 输入结束或错误 */ }
      
  2. printf 的返回值

    • 类型int

    • 行为:返回实际输出的字符数(不包括终止符 \0)。若出错(如格式化字符串无效),返回负数。

    • 示例

      int len = printf("Value: %d", 42); // len = 8("Value: 42" 共 8 字符)
      

Python 的 sys.stdinprint

  1. sys.stdin 的方法返回值

    • sys.stdin.read():返回整个输入内容(字符串),直到 EOF。

    • sys.stdin.readline():返回一行输入(包括换行符 \n),EOF 时返回空字符串 ''

    • 示例

      line = sys.stdin.readline()
      if line == '':  # 判断是否 EOFprint("Input ended.")
      
  2. print 的返回值

    • 类型None

    • 行为print 是 Python 的函数,仅执行输出操作,没有返回值。

    • 示例

      result = print("Hello")  # result = None
      

关键对比表

函数/方法 返回值类型 返回值含义 错误处理
cin >> var istream& 返回流对象本身,用于链式操作 检查流状态(如 cin.fail()
cout << value ostream& 返回流对象本身,用于链式操作 通常忽略,可检查 cout.good()
scanf int 成功匹配的输入项数量 检查返回值是否等于预期参数数量
printf int 成功输出的字符数 检查是否为负数
sys.stdin.read() str 输入的全部内容(字符串) 空字符串表示 EOF
sys.stdin.readline() str 单行输入内容(含换行符) 空字符串表示 EOF
print() None 无返回值 异常可能由输出流引发(如 IOError)

常见场景示例

  1. C++ 读取直到 EOF

    int x;
    while (cin >> x) {  // 当读取失败(如 EOF)时退出循环// 处理 x
    }
    
  2. C 安全读取输入

    int a;
    if (scanf("%d", &a) != 1) {fprintf(stderr, "Invalid input!");exit(1);
    }
    
  3. Python 逐行读取输入

    import sys
    for line in sys.stdin:line = line.strip()if not line:break# 处理 line
    

总结

  • C/C++:通过返回值或流状态显式处理错误。
  • Python:输入方法返回字符串,需手动处理类型和 EOF;print 无返回值。
  • Shell:输入输出为纯文本流,依赖外部工具解析(如 awk 处理数值)。





不同语言stdin, stdout,stderr详解

在C++和Python中,标准输入(stdin)、标准输出(stdout)和标准错误(stderr)是三个独立的流。cincout 是C++中的标准输入输出流,而 scanfprintf 是C语言的标准输入输出函数。sys.stdinsys.stdoutsys.stderr 则是Python中的对应概念。

C++中的处理

标准输出 (cout) 和标准错误 (cerr)

  • std::cout:用于标准输出(通常是终端屏幕)。
  • std::cerr:用于标准错误输出(也是通常显示在终端屏幕上,但与标准输出分开)。

示例:

#include <iostream>int main() {std::cout << "This is standard output." << std::endl;std::cerr << "This is standard error output." << std::endl;return 0;
}

使用 fprintf 处理 stderr

如果你使用的是C风格的I/O函数,可以使用 fprintf 来向 stderr 输出信息。

示例:

#include <cstdio>int main() {printf("This is standard output.\n");fprintf(stderr, "This is standard error output.\n");return 0;
}

Python中的处理

标准输入 (sys.stdin)、标准输出 (sys.stdout) 和标准错误 (sys.stderr)

  • sys.stdin:用于标准输入。
  • sys.stdout:用于标准输出。
  • sys.stderr:用于标准错误输出。

示例:

import syssys.stdout.write("This is standard output.\n")
sys.stderr.write("This is standard error output.\n")# 或者使用 print 函数指定文件参数
print("This is standard output.", file=sys.stdout)
print("This is standard error output.", file=sys.stderr)

总结

  • C++: 使用 std::coutstd::cerr 分别处理标准输出和标准错误输出。也可以使用 printffprintf(stderr, ...) 来分别处理标准输出和标准错误输出。
  • Python: 使用 sys.stdoutsys.stderr 分别处理标准输出和标准错误输出。可以通过 print 函数的 file 参数来指定输出流。

这些方法允许你将正常的程序输出和错误信息分离,这对于调试和日志记录非常有用。例如,你可以将正常的信息打印到控制台或日志文件,而将错误信息重定向到一个单独的日志文件中以便于分析。




代码实战


下面的所有代码均为自己手写,非官方参考答案,官方答案在这

第一题

1. A+B问题I
题目描述
你的任务是计算a+b。输入描述
输入包含一系列的a和b对,通过空格隔开。一对a和b占一行。输出描述
对于输入的每对a和b,你需要依次输出a、b的和。如对于输入中的第二对a和b,在输出中它们的和应该也在第二行。输入示例
3 4
11 40
输出示例
7
51

题解

C++:

#include<iostream>
using namespace std;
int main(){int a,b;while(cin>>a>>b){cout<<a+b<<'\n';}
}

C风格:

//代码1:#include<cstdio>
using namespace std;
int main(){int a,b;while(scanf("%d%d",&a,&b) == 2){printf("%d\n",a+b);}}//代码2:
#include<cstdio>
using namespace std;
int main(){int a,b;while(scanf("%d%d",&a,&b) != EOF){printf("%d\n",a+b);}}

python:

import sysif __name__ =="__main__": for line in sys.stdin:x,y = line.split(" ")#print(type(line))#print(line)print(int(x)+int(y))

第二题

2. A+B问题II
题目描述
计算a+b,但输入方式有所改变。输入描述
第一行是一个整数N,表示后面会有N行a和b,通过空格隔开。输出描述
对于输入的每对a和b,你需要在相应的行输出a、b的和。
如第二对a和b,对应的和也输出在第二行。
输入示例
2
2 4
9 21
输出示例
6
30
提示信息
注意,测试数据不仅仅一组。也就是说,会持续输入N以及后面的a和b

题解:

c&c++

#include<iostream>
#include<cstdio>
using namespace std;
/*int main(){int n,a,b;while(true){if(scanf("%d",&n) == 1){while(n--){scanf("%d%d",&a,&b);printf("%d\n",a+b);}   }else{break;}}}*/int main(){int n,a,b;while(cin>>n){while(n--){cin>>a>>b;cout<<a+b<<"\n";}}
}

python:

while 1:try:N = int(input())for i in range(N):l = list(map(int,input().split()))print(sum(l))except:break 

第三题

3. A+B问题III
题目描述
你的任务依然是计算a+b。输入描述
输入中每行是一对a和b。其中会有一对是0和0标志着输入结束,且这一对不要计算。输出描述
对于输入的每对a和b,你需要在相应的行输出a、b的和。
如第二对a和b,他们的和也输出在第二行。
输入示例
2 4
11 19
0 0
输出示例
6
30

题解:

python

while(1):mylist = list(map(int, input().split()))if mylist[0] == mylist[1] == 0:break;else:print(sum(mylist))

c++&c

#include<iostream>
using namespace std;
int main(){int a,b;while(true){cin>>a>>b;if(a==0&&b==0){break;}else{cout<<a+b<<endl;}}
}

第四题

4. A+B问题IV
题目描述
你的任务是计算若干整数的和。输入描述
每行的第一个数N,表示本行后面有N个数。如果N=0时,表示输入结束,且这一行不要计算。输出描述
对于每一行数据需要在相应的行输出和。输入示例
4 1 2 3 4
5 1 2 3 4 5
0 
输出示例
10
15

python

import sys
while(1):mylist = list(map(int, input().split()))if mylist[0] == 0:breakprint(sum(mylist[1:]))

c++

#include<iostream>
using namespace std;
int main(){int n;while(cin>>n && n!=0){int tmp;int sum = 0;while(n--){cin>>tmp;sum+=tmp;}cout<<sum<<endl;}
}

第五题

5. A+B问题VII
题目描述
你的任务是计算两个整数的和。
输入描述
输入包含若干行,每行输入两个整数a和b,由空格分隔。
输出描述
对于每组输入,输出a和b的和,每行输出后接一个空行。
输入示例
2 4
11 19
输出示例
630

题解

python

while 1:try:mylist = list(map(int, input().split()))print(sum(mylist),'\n')except:break

c++

#include<iostream>
using namespace std;
int main(){int a,b;while(cin>>a>>b){cout<<a+b<<"\n\n";}}

第六题

6. A+B问题VIII
题目描述
你的任务是计算若干整数的和。
输入描述
输入的第一行为一个整数N,接下来N行每行先输入一个整数M,然后在同一行内输入M个整数。输出描述
对于每组输入,输出M个数的和,每组输出之间输出一个空行。
输入示例
3
4 1 2 3 4
5 1 2 3 4 5
3 1 2 3
输出示例
10156
提示信息
注意以上样例为一组测试数据,后端判题会有很多组测试数据,也就是会有多个N的输入
例如输入可以是:
3
4 1 2 3 4
5 1 2 3 4 5
3 1 2 3
3
4 1 2 3 4
5 1 2 3 4 5
3 1 2 3
输出则是
10156
10156
只保证每组数据间是有空行的。但两组数据并没有空行

题解

python

while 1:try:N = int(input())for i in range(N):fin = list(map(int,input().split()))print(sum(fin[1:]))if i != N-1:print()except:break

c++

#include<iostream>
using namespace std;
int main(){int n;while(cin>>n){int n_loop;int cnt_loop;int tmp_loop;while(n--){cin>>n_loop;cnt_loop = 0;while(n_loop--){cin>>tmp_loop;cnt_loop+=tmp_loop;}cout<<cnt_loop<<endl;if(n!=0){cout<<"\n";}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/901947.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WinSCP主机名

连接Wifi的情况下,Ubuntu命令行输入"ifconfig",如图即为主机名当我在使用网线时,打开虚拟机显示的ifconfig却是这样:此时连接WinSCP是行不通的因此只能拔掉网线,在WiFi情况下,重启虚拟机,命令行如下: sudo shutdown -r now 然后再重新接入WinSCP即可。 只要在…

从0到1制作智慧医院,全流程解读

在科技飞速发展的今天,智慧医院已成为医疗行业变革的重要方向。想象一下,患者走进医院,无需繁琐的排队挂号,通过智能导诊系统就能快速找到就诊科室;医生借助大数据和人工智能,能更精准地诊断病情、制定治疗方案;医院管理者通过实时的数据监控,优化资源调配,提升运营效…

Pydantic多态模型:用鉴别器构建类型安全的API接口

title: Pydantic多态模型:用鉴别器构建类型安全的API接口 date: 2025/3/20 updated: 2025/3/20 author: cmdragon excerpt: Pydantic的鉴别器机制通过字段显式声明类型,实现自动化路由,避免了传统多态实现中的手动类型判断。基础鉴别器定义通过字段声明和类型标识,实现自…

固件打包流程

基础知识: SHA-256类型: 哈希函数 用途: 用于生成数据的唯一指纹(哈希值),确保数据的完整性。 特性: 不可逆、快速计算、抗碰撞性。RSA类型: 非对称加密算法 用途: 主要用于加密数据、数字签名和密钥交换。 特性: 使用一对密钥(公钥和私钥),其中公钥用于加密或验证签名,…

C语言入口函数

c语言入口函数必须是main

从数据孤岛到信息互通,多宁生物如何用CRM打破集团型企业的协同难题?

上海多宁生物科技股份有限公司(简称“多宁生物”)是一家一站式生物工艺解决方案提供商,提供生物制药产品从研发到商业化生产的全面解决方案,包括试剂及耗材、仪器设备和服务。公司经营生物工艺解决方案、实验室产品及服务两大业务线,帮助客户实现高效、稳定、质量及成本可…

五分钟带你看懂 NVIDIA 和 AI 的未来

(配图:Photo by BoliviaInteligente on Unsplash)前言:2025 年 3 月 18 日,在美国加州圣何塞举行的 GTC 2025 大会上,NVIDIA CEO 黄仁勋发表了长达两小时的主题演讲,详细介绍了 NVIDIA 的未来路线图。 这场被誉为“AI 超级碗”的盛会,吸引了全球开发者、创新者和行业领导…

初识 WebSocket 协议

什么是 WebSocket WebSocket 是一种网络通信协议,是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 属于应用层协议,它基于 TCP 传输协议,并复用 HTTP 的握手通道。 为什么出现 WebSocket 我们已经拥有了 HTTP 协议,为什么还要搞出一套 WebSocket…

易基因:WGBS+ChIP-seq技术揭示Cdx2转录因子在发育与稳态中的动态结合机制|NC/IF14.7

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 Cdx2是一个关键的转录因子,在小鼠肠道上皮细胞的发育过程中起着决定性的作用。它在胚胎期和成年期的肠道上皮细胞中都有表达,但其结合的基因组位点在发育和成年期有所不同。DNA甲基化是一种表观遗传修饰,通…

FALL

FALL 信息收集 扫描目标主机ip ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:84:b2:cc, IPv4: 192.168.158.143 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.158.1 00:50:56:c0:0…

信创龙头股在政策支持下的投资机会解读

信创产业,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。近年来,随着政策的大力支持,信创产业发展势头迅猛,信创龙头股也备受投资者关注。在政策东风的助力下,信创龙头股蕴含着丰富的投资机会,值得深入剖析。 政策支…

通过 INFINI Console 集中管理极限网关配置

之前有做过介绍实现极限网关(INFINI Gateway) 配置动态加载,这是一个 Gateway 实例的操作,直接在服务器上修改配置文件。如果有多个 Gateway 实例需要调整,登录多台主机修改配置文件就有些繁琐,有没有简便的方法呢? 答案是: 当然有! INFINI Gateway 有配套的管理页面,…