卡码网语言基础课 | 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:引用的作用域(作用范围)通常是在声明它的函数或代码块内,超出作用域后引用将无效。

相关推荐
奋斗的小花生36 分钟前
c++ 多态性
开发语言·c++
魔道不误砍柴功38 分钟前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
pianmian139 分钟前
python数据结构基础(7)
数据结构·算法
闲晨41 分钟前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程1 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
UestcXiye2 小时前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
Chrikk2 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*2 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue2 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man2 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang