【C++】P1957 口算练习题


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯题目描述
    • 输入格式:
    • 输出格式:
  • 💯我的做法
    • 代码实现:
  • 💯老师的做法
    • 代码实现:
  • 💯对比分析
  • 💯拓展与优化
  • 💯总结
    • 一开始的错误做法


在这里插入图片描述


💯前言

  • 在编程学习过程中,C++ 语言为我们提供了强大的控制能力和灵活的操作方式。在本次学习中,我们面对的是一个简单的算术口算题目的处理任务。任务要求通过程序自动处理多个口算算式,输出完整的算式、其计算结果,并计算算式的总长度。这个问题看似简单,但可以通过多种方式解决,过程中涉及到字符串拼接、运算符判断和数据存储等基础编程技术。
    在本次讨论中,我们将深入分析两种不同的解决方法:我提出的做法与老师的做法。我们将详细对比这两种方法的思路、代码实现,并进行优化和拓展,以便对 C++ 编程的理解更为深刻。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

P1957 口算练习题
在这里插入图片描述

题目要求我们处理一组口算题目,每道题目可能包括加法、减法或乘法操作。每道题的输入由两个或三个数据组成,若有三个数据,第一个表示运算符(a 表示加法,b 表示减法,c 表示乘法),接下来的两个数据为参与运算的数值;若只有两个数据,则表示继承上一道题的运算符。

我们需要输出每道题的完整算式,并且输出算式的总长度。以下是题目的完整描述:

输入格式:

4
a 64 46
275 125
c 11 99
b 46 64

输出格式:

64+46=110
9
275+125=400
11
11*99=1089
10
46-64=-18
9

💯我的做法

我的实现方法着眼于输入的处理与字符串的拼接,基本流程如下:

  1. 输入读取:首先读取题目数量 i,然后循环处理每一道算式。每道算式可以是完整的带有运算符的输入,也可以是继承上题的运算符。
  2. 算式计算:对于每道算式,根据运算符 a, b, 或 c 来决定进行加法、减法或乘法操作。
  3. 字符串拼接:利用字符串的拼接(+=)来构造完整的算式表达式,并计算结果。
  4. 输出:输出每道算式及其结果,最后输出算式的总长度。

代码实现:

#include <iostream>
#include <string>
using namespace std;

int main()
{
	int  i;
	cin >> i;
	int a, b;
	string temp, ysf;
	while(i--)
	{
		string s;
		cin >> temp;
		if(temp == "a" || temp == "b" || temp == "c")
		{
			cin >> a >> b;
			if(temp == "a")
			{
				s += to_string(a);
				s += '+';
				s += to_string(b);
				s += '=';
				s += to_string(a + b);
			}
			else if(temp == "b")
			{
				s += to_string(a);
				s += '-';
				s += to_string(b);
				s += '=';
				s += to_string(a - b);
			}
			else if(temp == "c")
			{
				s += to_string(a);
				s += '*';
				s += to_string(b);
				s += '=';
				s += to_string(a * b);
			}
			ysf = temp;
		}
		else
		{
			a = stoi(temp);
			cin >> b;
			if(ysf == "a")
			{
				s += to_string(a);
				s += '+';
				s += to_string(b);
				s += '=';
				s += to_string(a + b);
			}
			else if(ysf == "b")
			{
				s += to_string(a);
				s += '-';
				s += to_string(b);
				s += '=';
				s += to_string(a - b);
			}
			else
			{
				s += to_string(a);
				s += '*';
				s += to_string(b);
				s += '=';
				s += to_string(a * b);
			}
		}
		
		cout << s << endl;
		cout << s.size() << endl;
	}
	
	return 0;
}

💯老师的做法

老师的做法与我的实现思路相似,但有一些不同之处。老师的代码在结构上稍显复杂,特别是在输入和字符串拼接部分的处理上,且做了更多的优化来处理继承运算符的情况。

代码实现:

int main()
{
    int n = 0;
    cin >> n;
    string op;
    string num1;
    string num2;
    string last;
    int ret = 0;

    while (n--)
    {
        string ans;
        cin >> op;

        if (op == "a" || op == "b" || op == "c")
        {
            cin >> num1 >> num2;
            int n1 = stoi(num1);
            int n2 = stoi(num2);
            ans += num1;

            if (op == "a")
            {
                ret = n1 + n2;
                ans += "+";
            }
            else if (op == "b")
            {
                ret = n1 - n2;
                ans += "-";
            }
            else
            {
                ret = n1 * n2;
                ans += "*";
            }
            last = op;
        }
        else
        {
            num1 = op;
            cin >> num2;
            int n1 = stoi(num1);
            int n2 = stoi(num2);
            ans += num1;

            if (last == "a")
            {
                ret = n1 + n2;
                ans += "+";
            }
            else if (last == "b")
            {
                ret = n1 - n2;
                ans += "-";
            }
            else
            {
                ret = n1 * n2;
                ans += "*";
            }
        }
        ans += (num2 + "=" + to_string(ret));
        cout << ans << endl;
        cout << ans.size() << endl;
    }
    return 0;
}

💯对比分析

  1. 结构差异

    • 我的做法中,我们根据输入的运算符判断是否更新运算符,并且用 last_op 来记住上一题的运算符,保证后续算式的正确计算。
    • 老师的做法稍微复杂一些,采用了更显式的变量存储(如 last 变量)。另外,老师在每次处理完一个算式后,拼接完成的字符串才会输出。
  2. 字符串拼接

    • 我的做法通过直接将 +-* 等运算符拼接进 ans 字符串。
    • 老师的做法在拼接过程中,将运算符的插入和结果的转换更加细化,也做了更精确的类型转换处理(使用 stoi 将字符串转换为整数)。
  3. 处理继承运算符

    • 我的做法是依赖 last_op 来判断是否使用上一题的运算符。
    • 老师的做法在这一点上比较细致,利用了 last 变量来确保后续运算使用的是正确的运算符。

💯拓展与优化

  1. 代码优化

    • 对于运算符和结果拼接部分,使用了 += 拼接字符串,但如果问题较为复杂或涉及到更多操作,可能会导致拼接效率不高。可以考虑使用 ostringstream 来拼接字符串,这样可以提高性能。
  2. 用户输入优化

    • 可以增加输入校验,避免用户输入错误的数据类型(如非数字输入等)。
  3. 更广泛的应用

    • 这类算术问题不仅限于加法、减法和乘法。如果要处理更多运算符(如除法、取余等),可以通过扩展运算符判断来完成。
  4. 函数化

    • 该问题的不同部分(如运算符判断、算式拼接、输出结果等)可以通过函数化进行封装,提高代码的模块化和复用性。

💯总结

本次学习和讨论了如何用 C++ 语言处理简单的口算算式,通过两种不同的实现方法(我的做法与老师的做法),我们掌握了如何判断运算符、处理继承运算符的情况,并输出结果与算式的总长度。通过对比分析,我们看到了两种做法的异同与各自的优缺点。

在优化方面,我们提出了改进的思路,如何提高代码性能、增强可扩展性,以及如何处理更多复杂的运算符类型。总体来说,这道题目的解决方案为我们提供了一个很好的编程练习机会,帮助我们更好地理解字符串操作、控制流程和输入输出的细节。

一开始的错误做法

#include <iostream>
#include <string>
using namespace std;

int main()
{
	int i = 0;
	cin >> i;
	int opera = 0;
	string s;
	while(i--)
	{
		int index = 0, a = 0, b = 0;
		while(cin >> s)
		{
			index++;
			if(index == 1)
			{
				if(s[i] == 'a')
					opera = 1;
				else if(s[i] == 'b')
					opera = 2;
				else if(s[i] == 'c')
					opera = 3;
				else
					a = stoi(string(1, s[i]));  // 将字符 s[i] 转换为字符串后再使用 stoi
			}
			
			if(index == 2 && a != 0)
				b = stoi(string(1, s[i]));
			else if(index == 2 && a == 0)
				a = stoi(string(1, s[i]));
			
			if(index == 3)
				b = stoi(string(1, s[i])); 

		}
		if(opera == 1)
			cout << a << "+" << b << "=" << (a + b) << endl;
		else if(opera == 2)
			cout << a << "-" << b << "=" << (a - b) << endl;
		else
			cout << a << "*" << b << "=" << (a * b) << endl;
	}
	
	return 0;
}

还有,要注意变量的作用域


在这里插入图片描述


在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

学习C++的建议

C++ 是一门强大且广泛应用的编程语言,无论是系统开发、游戏开发还是高性能计算,它都有不可替代的地位。然而,学习C++的道路可能是陡峭的,为了帮助你更高效地掌握这门语言,我总结了一些学习建议和经验。


1. 理解C++的基础
学习重点:

  1. 掌握基本语法
    • 学会声明变量、条件语句、循环、函数等核心语法。
    • 掌握数组、指针、引用等基础知识。
  2. 熟悉标准输入输出
    • 掌握 cincout 的用法。
    • 理解格式化输出,例如 std::setwstd::fixed
  3. 记住编译器的角色
    • 理解源代码如何通过编译器转换为可执行程序,选择一款好的IDE(如Visual Studio、Clion、VSCode)。

建议:用大量小程序练习这些基础语法,比如写一个计算器、模拟猜数字游戏等。


2. 深入学习C++的特性
学习重点:

  1. 面向对象编程(OOP)
    • 理解类和对象,熟悉如何定义类、成员变量和成员函数。
    • 掌握封装、继承、多态三大核心特性。
  2. 内存管理
    • 理解指针的用法,掌握动态内存分配(newdelete)。
    • 学习如何避免内存泄漏,熟悉智能指针(如std::unique_ptrstd::shared_ptr)。
  3. 标准模板库(STL)
    • 熟悉常用的容器(如vectormapset)和算法(如sortfind)。
    • 掌握迭代器的用法。
  4. 异常处理
    • 学习使用try-catch块处理异常。
    • 理解异常的用途以及如何设计健壮的代码。

建议:尝试开发一个小型项目,比如一个学生管理系统,综合应用类、STL、指针和动态内存分配。


3. 掌握进阶内容
学习重点:

  1. 模板
    • 理解函数模板和类模板,掌握泛型编程思想。
    • 学习模板特化和模板元编程的基本概念。
  2. 多线程与并发
    • 学习 C++11 提供的多线程支持(如std::thread)。
    • 熟悉互斥锁(std::mutex)和条件变量(std::condition_variable)。
  3. C++与C的兼容性
    • 学习如何在C++中使用C语言代码,理解C和C++的区别。
    • 掌握C风格字符串(char[])和C++字符串(std::string)的转换。

建议:在这一阶段,可以挑战更复杂的项目,比如开发一个小型的HTTP服务器,学习网络编程并结合多线程。


4. 学习资源与实践方法
学习资源:

  1. 书籍
    • 《C++ Primer》:非常适合初学者的经典书籍。
    • 《Effective C++》:进阶学习C++最佳实践的指南。
    • 《The C++ Programming Language》:Bjarne Stroustrup(C++之父)的权威著作。
  2. 在线课程
    • Coursera 上的 C++ 编程课程。
    • YouTube 上免费的 C++ 系列教程。
  3. 社区与文档
    • 参与C++相关的论坛(如CSDN、Stack Overflow)。
    • 阅读官方文档(https://en.cppreference.com)。

实践方法:

  1. 多写代码,多调试
    • 每学一个概念后,写至少两个示例代码并进行调试。
  2. 做小项目
    • 从简单的控制台程序开始,比如文件读写、计算器、小游戏等。
    • 慢慢过渡到图形界面或网络程序开发。
  3. 阅读他人代码
    • 阅读开源项目的代码,理解优秀代码的设计思路。
  4. 参加编程比赛
    • 比如 LeetCode 或 Codeforces,可以帮助你提升算法能力和C++的熟练度。

5. 保持耐心与兴趣
学习C++可能会面临以下困难:

  1. 复杂的语法:如模板、智能指针、多线程等。
  2. 调试困难:指针错误、内存泄漏、未定义行为可能让人头疼。

如何应对:

  • 将大问题拆解成小问题,逐步解决。
  • 不断重复基础知识,以加深理解。
  • 保持兴趣,尝试一些有趣的项目,比如写一个游戏、制作一个简单的图形程序。

小结
学习C++需要一个循序渐进的过程,从基础语法到面向对象编程,再到进阶的模板和并发编程,每一步都需要耐心和实践。通过充分利用学习资源、进行大量编码练习,以及挑战实际项目,你一定可以成为C++的高手。记住,学习的核心在于理解,而非死记硬背。

祝你学有所成,享受C++编程的乐趣!


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux系统】信号:再谈OS与内核区、信号捕捉、重入函数与 volatile

再谈操作系统与内核区 1、浅谈虚拟机和操作系统映射于地址空间的作用 我们调用任何函数&#xff08;无论是库函数还是系统调用&#xff09;&#xff0c;都是在各自进程的地址空间中执行的。无论操作系统如何切换进程&#xff0c;它都能确保访问同一个操作系统实例。换句话说&am…

LabVIEW双光子成像系统:自主创新,精准成像,赋能科研

双光子成像系统&#xff1a;自主创新&#xff0c;精准成像&#xff0c;赋能科研 第一部分&#xff1a;概述 双光子成像利用两个低能量光子同时激发荧光分子&#xff0c;具有深层穿透、高分辨率、低光损伤等优势。它能实现活体深层组织的成像&#xff0c;支持实时动态观察&…

「全网最细 + 实战源码案例」设计模式——策略模式

核心思想 享元模式&#xff08;Flyweight Pattern&#xff09;是一种行为型设计模式&#xff0c;用于定义一系列算法或策略&#xff0c;将它们封装成独立的类&#xff0c;并使它们可以相互替换&#xff0c;而不影响客户端的代码&#xff0c;提高代码的可维护性和扩展性。 结构…

安全策略实验

安全策略实验 1.拓扑图 2.需求分析 需求&#xff1a; 1.VLAN 2属于办公区&#xff0c;VLAN 3属于生产区 2.办公区PC在工作日时间&#xff08;周一至周五&#xff0c;早8到晚6&#xff09;可以正常访问OA server其他时间不允许 3.办公区PC可以在任意时刻访问Web Server 4.生产…

一文了解边缘计算

什么是边缘计算&#xff1f; 我们可以通过一个最简单的例子来理解它&#xff0c;它就像一个司令员&#xff0c;身在离炮火最近的前线&#xff0c;汇集现场所有的实时信息&#xff0c;经过分析并做出决策&#xff0c;及时果断而不拖延。 1.什么是边缘计算&#xff1f; 边缘计算…

对象的实例化、内存布局与访问定位

一、创建对象的方式 二、创建对象的步骤: 一、判断对象对应的类是否加载、链接、初始化: 虚拟机遇到一条new指令&#xff0c;首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否已经被加载、解析和初始化…

Altium Designer绘制原理图时画斜线的方法

第一步&#xff1a;检查设置是否正确 打开preferences->PCB Editor ->Interactive Routing->Interactive Routing Options->Restrict TO 90/45去掉勾选项&#xff0c;点击OK即可。如下图所示&#xff1a; 然后在划线时&#xff0c;按下shift空格就能够切换划线…

【R语言】环境空间

一、环境空间的特点 环境空间是一种特殊类型的变量&#xff0c;它可以像其它变量一样被分配和操作&#xff0c;还可以以参数的形式传递给函数。 R语言中环境空间具有如下3个特点&#xff1a; 1、对象名称唯一性 此特点指的是在不同的环境空间中可以有同名的变量出现&#x…

NeuralCF 模型:神经网络协同过滤模型

实验和完整代码 完整代码实现和jupyter运行&#xff1a;https://github.com/Myolive-Lin/RecSys--deep-learning-recommendation-system/tree/main 引言 NeuralCF 模型由新加坡国立大学研究人员于 2017 年提出&#xff0c;其核心思想在于将传统协同过滤方法与深度学习技术相结…

【ChatGPT:开启人工智能新纪元】

一、ChatGPT 是什么 最近,ChatGPT 可是火得一塌糊涂,不管是在科技圈、媒体界,还是咱们普通人的日常聊天里,都能听到它的大名。好多人都在讨论,这 ChatGPT 到底是个啥 “神器”,能让大家这么着迷?今天咱就好好唠唠。 ChatGPT,全称是 Chat Generative Pre-trained Trans…

c++ 定点 new 及其汇编解释

&#xff08;1&#xff09; 代码距离&#xff1a; #include <new> // 需要包含这个头文件 #include <iostream>int main() {char buffer[sizeof(int)]; // 分配一个足够大的字符数组作为内存池int* p new(&buffer) int(42); // 使用 placement new…

Linux系统之whereis命令的基本使用

Linux系统之whereis命令的基本使用 一、whereis命令介绍二、whereis命令的使用帮助2.1 whereis命令的帮助信息2.2 whereis命令帮助解释 三、whereis命令的基本使用3.1 查找命令的位置3.2 仅查找二进制文件3.3 仅查找手册页3.4 输出实际使用的查找路径3.5 指定自定义搜索路径 四…

CH340G上传程序到ESP8266-01(S)模块

文章目录 概要ESP8266模块外形尺寸模块原理图模块引脚功能 CH340G模块外形及其引脚模块引脚功能USB TO TTL引脚 程序上传接线Arduino IDE 安装ESP8266开发板Arduino IDE 开发板上传失败上传成功 正常工作 概要 使用USB TO TTL&#xff08;CH340G&#xff09;将Arduino将程序上传…

整形的存储形式和浮点型在计算机中的存储形式

在计算机科学的底层世界里&#xff0c;数据存储是基石般的存在。不同数据类型&#xff0c;如整形与浮点型&#xff0c;其存储方式犹如独特的密码&#xff0c;隐藏着计算机高效运行的秘密。理解它们&#xff0c;是深入掌握编程与计算机原理的关键。 一、整形的存储形式 原码、反…

无人机PX4飞控 | PX4源码添加自定义uORB消息并保存到日志

PX4源码添加自定义uORB消息并保存到日志 0 前言 PX4的内部通信机制主要依赖于uORB&#xff08;Micro Object Request Broker&#xff09;&#xff0c;这是一种跨进程的通信机制&#xff0c;一种轻量级的中间件&#xff0c;用于在PX4飞控系统的各个模块之间进行高效的数据交换…

QMK启用摇杆和鼠标按键功能

虽然选择了触摸屏&#xff0c;我仍选择为机械键盘嵌入摇杆模块&#xff0c;这本质上是对"操作连续性"的执着。   值得深思的是&#xff0c;本次开发过程中借助DeepSeek的代码生成与逻辑推理&#xff0c;其展现的能力已然颠覆传统编程范式&#xff0c;需求描述可自动…

Rust 所有权特性详解

Rust 所有权特性详解 Rust 的所有权系统是其内存安全的核心机制之一。通过所有权规则&#xff0c;Rust 在编译时避免了常见的内存错误&#xff08;如空指针、数据竞争等&#xff09;。本文将从堆内存与栈内存、所有权规则、变量作用域、String 类型、内存分配、所有权移动、Cl…

基于深度学习的视觉检测小项目(十七) 用户管理后台的编程

完成了用户管理功能的阶段。下一阶段进入AI功能相关。所有的资源见文章链接。 补充完后台代码的用户管理界面代码&#xff1a; import sqlite3from PySide6.QtCore import Slot from PySide6.QtWidgets import QDialog, QMessageBoxfrom . import user_manage # 导入使用ui…

ubuntuCUDA安装

系列文章目录 移动硬盘制作Ubuntu系统盘 前言 根据前篇“移动硬盘制作Ubuntu系统盘”安装系统后&#xff0c;还不能够使用显卡。 如果需要使用显卡&#xff0c;还需要进行相关驱动的安装&#xff08;如使用的为Nvidia显卡&#xff0c;就需要安装相关的Nvidia显卡驱动&#xff…

Docker Compose的使用

文章首发于我的博客&#xff1a;https://blog.liuzijian.com/post/docker-compose.html 目录 Docker Compose是什么Docker Compose安装Docker Compose文件Docker Compose常用命令案例&#xff1a;部署WordPress博客系统 Docker Compose是什么 Docker Compose是Docker官方的开源…