卡码网语言基础课 | 11. 句子缩写

目录

[一、 字符串大小的比较](#一、 字符串大小的比较)

[二、 ASCII码值](#二、 ASCII码值)

[三、 基本框架代码](#三、 基本框架代码)

[四、 解题思路](#四、 解题思路)

[4.1 首字母问题](#4.1 首字母问题)

[4.2 判定小写字母](#4.2 判定小写字母)

[4.3 小写字母转换为大写字母](#4.3 小写字母转换为大写字母)

五、空格判断

[六、 代码模块化](#六、 代码模块化)

[6.1 满足的条件](#6.1 满足的条件)

[6.2 代码完善](#6.2 代码完善)

[七、 题目解答](#七、 题目解答)

[7.1 原始代码](#7.1 原始代码)

[7.2 改进代码](#7.2 改进代码)

[八、 拓展与延伸](#八、 拓展与延伸)

[8.1 形参和实参](#8.1 形参和实参)

[8.2 引用](#8.2 引用)


通过本次练习,将会学习到以下C++知识点:(同时强化字符串的练习)

  • 字符大小的比较、字符运算、字符拼接
  • ASCII码
  • **getchar()**函数的使用
  • 函数的定义和使用
  • 函数的形参和实参
  • 引用**&**

题目:输出一个词组中每个单词的首字母的大写组合。输入中的第一行n代表,之后一共有n组输入数据。其中,每行单词多个,每个单词长度不一,单词之间空格数不一。

cpp 复制代码
示例:
输入:
1
ad dfa     fgs

输出:
ADF

一、 字符串大小的比较

在字符集中的ASCII码值来确定

二、 ASCII码值

三、 基本框架代码

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
int main(){
    int n;
    cin >> n; //输入接收n行
    getchar(); //从输入中获取一个字符
    
}

注意这里使用了 getchar() 函数来吸收一个回车符,因为在输入 n 之后通常需要输入回车符才会输入下一行。

cpp 复制代码
//原本: cout >> n >> endl;

之后仍然可以使用**while** 循环来处理n行数据,每一行数据使用**getline(cin, n)**来进行接收。

cpp 复制代码
string s; // 定义变量s, 接收每行输入的字符串
while(n--) {
   getline(cin, s); // 从标准输入读取一行字符串,存储在字符串变量 s中
   string result; //  定义变量result, 用来输出经过处理后的结果
}

四、 解题思路

4.1 首字母问题

题目要求输出单词首字母为大写,即存在两种情况,第一种为直接就是大写,另一种就是为小写。

如果第一个字符是小写字符,则将之转换成大写字符,再进行拼接。

4.2 判定小写字母

小写字母从 'a' 到 'z' 对应的ASCII码值是从 97 到 122,且是连续的。

即如果输入的字符>=a, 并且<=z, 则一定在**a和z**的范围之内,也就是一定是小写字母。

cpp 复制代码
// 如果第一个字符是小写字符
if (s[0] >= 'a' && s[0]  <= 'z') {

}

4.3 小写字母转换为大写字母

大小写字符之间的差值是32, 将小写字符做减法运算,就可以得到对应的大写字符。

cpp 复制代码
// 如果输入的字符是小写字符,则进行转换
if (s[0] >= 'a' && s[0]  <= 'z') {
  // ASCII码中小写字母和大写字母相差32
    s[0] -= 32;
}
result += s[0];// 将每行的第一个字符转换成大写后添加到result中

五、空格判断

因为在单词之间,存在数量不一的空格,因此需要做出合理判断。

cpp 复制代码
for (int i = 1; i < s.size() - 1; i++) { // 单词之间可能有多个空格
  // 如果当前字符是空格,并且下一个字符不是空格
      if (s[i] == ' ' && s[i + 1] != ' ') {
      // 判定下一个字符是否是小写字母,如果是则转换成大写
      if (s[i + 1] >= 'a' && s[i + 1]  <= 'z') {
        s[i + 1] -= 32;
      }
      // 将下一个字符拼接到结果result中
      result += s[i + 1]
    }
}

六、 代码模块化

由于4.2和4.3中的步骤和代码,在本次题目中重复使用,因此为了代码简洁和后续的方便维护和修改,需要将代码进行模块化操作,从而增加代码的复用性和可维护性。

6.1 满足的条件

如果想要定义一个将小写字符转换成大写字符的函数,需要满足以下条件:

  • 返回类型:返回结果是经过转换后的大写字符,所以返回类型为**char**
  • 函数名:可以自定义,这里使用**changeChar**作为函数的名称
  • 形参列表:之前的形参列表为空,而一般的形参列表通常包括参数类型和参数名称。参数类型表示参数的数据类型,可以是内置数据类型(例如整数、字符、浮点数等)、用户自定义的数据类型。参数名称通常是用来描述参数的有意义的名称,可以在函数体内部使用,这里接收一个字符作为输入,所以形参列表类型为**char**, 参数名称可以用a表示, 引用传递&意味着函数可以修改传递给它的参数。

6.2 代码完善

cpp 复制代码
// char代表返回类型,changeChar代表函数名称,char a表示函数接收一个字符a作为参数
char changeChar(char &a) {
  if (a >= 'a' && a <= 'z') a -= 32;
  // 返回类型为char, 最终还要返回a
  return a;
}

七、 题目解答

7.1 原始代码

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
int main(){
    int n;
    string s;
    cin >> n; //输入接收n行
    getchar(); //从输入中获取一个字符
    while(n--){
        getline(cin,s); //接收新的一行
        string result; //设定结果存储的字符串result
        
        //将首字母小写转换为大写
        if(s[0] >= 'a' && s[0] <= 'z'){
            s[0] -=32; //大小写之间相差32
        }
        
        //将首字母链接到结果中
        result += s[0];
        
        //遍历后续整个字符串
        for(int i = 1; i < s.size() - 1; i++){//i=1即是从第二个字母开始
            
            //若当前字符为空格,下一个字符不是空格,则说明下一个字符是新单词
            if(s[i] == ' ' && s[i+1] != ' '){
                //判定新单词是否为小写,若是,则转换
                if(s[i+1] >= 'a' && s[i+1] <= 'z'){
                    s[i+1] -= 32;
                }
                
                //将新首字母链接到结果中
                result += s[i+1];
            }
            
        }
        
        cout << result << endl;
        
    }
    
}

7.2 改进代码

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

//小写字母转换为大写字母的函数
char changeChar(char a){
    if(a >= 'a' && a <= 'z'){
        a -= 32;
    }
    return a;
}


int main(){
    int n;
    string s,result;
    cin >> n; //输入接收n行
    getchar(); //从输入中获取一个字符
    while(n--){
        result = ""; //PS:该步骤不可缺少

        //或者均可
        //string result;

        getline(cin,s); //接收新的一行
        
        result += changeChar(s[0]);  // 将s[0]传递到参数进行处理,转换成大写字母
        
        //遍历后续整个字符串
        for(int i = 1; i < s.size() - 1; i++){//i=1即是从第二个字母开始
            
            //若当前字符为空格,下一个字符不是空格,则说明下一个字符是新单词
            if(s[i] == ' ' && s[i+1] != ' '){
                result += changeChar(s[i+1]); //将s[i+1传递到参数进行处理,转换成大写字母
            }
            
        }
        cout << result << endl;
        
    }
    
}

八、 拓展与延伸

8.1 形参和实参

实参和形参是与函数调用相关的两个很重要的概念,用于在函数调用时传递数据和接收数据。

形参是函数定义中声明的参数,位于函数的参数列表中。形参的作用是定义函数接受的参数的类型和名称,定义的形参只在函数执行期间有效,在函数执行完毕后会被销毁。而且它作用的范围(作用域)仅限于函数体内部,因此它们与函数外部的变量名称可以相同,而不会发生冲突。

cpp 复制代码
void printSum(int a, int b) { // a和b是传递的形参,只在函数体{}中有效
  int sum = a + b;
  cout << sum << endl;
}

实参是函数调用中传递给函数的具体值或变量,实参传递的值必须与函数的形参类型匹配,否则会发生类型错误。

cpp 复制代码
int main() {
    int x = 5, y = 3;
    printSum(x, y); // 这里进行了函数调用,x和y是实参
      cout << x << y << endl;
    return 0;
}

8.2 引用

在声明引用时,需要在变量名前使用 & 符号。引用必须在声明时进行初始化,并且一旦初始化,就不能改变引用的目标。

cpp 复制代码
int a = 10;
int &ref = a; // 声明并初始化引用为a

当函数传递参数时,通常会创建参数的副本。使用引用参数可以避免不必要的参数复制,这对于大型数据结构(如数组)尤其有用,因为复制这些数据结构会产生显著的开销。

cpp 复制代码
#include <iostream>
using namespace std;

void changeValue(int & a) {
    a = 100; // 修改调用方传递的变量的值
}

int main() {
    int x = 10;
    cout << x << endl;
    changeValue(x); // 传递x的引用给函数
    cout << x << endl; // x的值被函数修改为100
    return 0;
}

PS:引用的作用域(作用范围)通常是在声明它的函数或代码块内,超出作用域后引用将无效。

相关推荐
StrokeAce1 小时前
linux桌面软件(wps)内嵌到主窗口后的关闭问题
linux·c++·qt·wps·窗口内嵌
一颗花生米。2 小时前
深入理解JavaScript 的原型继承
java·开发语言·javascript·原型模式
问道飞鱼2 小时前
Java基础-单例模式的实现
java·开发语言·单例模式
学习使我快乐012 小时前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
通信仿真实验室3 小时前
(10)MATLAB莱斯(Rician)衰落信道仿真1
开发语言·matlab
勿语&3 小时前
Element-UI Plus 暗黑主题切换及自定义主题色
开发语言·javascript·ui
家有狸花4 小时前
VSCODE驯服日记(三):配置C++环境
c++·ide·vscode
dengqingrui1234 小时前
【树形DP】AT_dp_p Independent Set 题解
c++·学习·算法·深度优先·图论·dp
C++忠实粉丝4 小时前
前缀和(8)_矩阵区域和
数据结构·c++·线性代数·算法·矩阵
ZZZ_O^O5 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树