Day 6

每日一题

在这里插入图片描述

题目

题目描述:
小明正在做作业。老师给了他一些文章,让他说出每个字母出现的次数。小明对这个问题无从下手,你可以帮帮他吗?
输入格式
输入行包含一篇文章,所有字母都是小写的。你只需要数一数每个字母的数量。文章的长度 l(0≤l≤10
5
)。
输出格式
针对输入的文章,你必须有序说出每个字母出现的次数 n。n 是一个正整数,同时字母顺序为从“a”到“z”。正整数之间以空格间隔。
输入输出样例
输入样例1
hello, this is my first acm contest! work hard for hdu acm.
输出样例1
3 0 3 2 2 2 0 4 3 0 1 2 3 1 4 0 0 4 4 4 1 0 1 0 1 0
说明/提示
只需统计各字母出现次数,无需计算符号

Java写法:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        int[] cnt = new int[26];
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= 'a' && c <= 'z') {
                cnt[c - 'a']++;
            }
        }
        for (int i = 0; i < 26; i++) {
            System.out.print(cnt[i] + " ");
        }
    }
}

Tips:

  1. 在 ASCII 编码中,小写字母 az 对应的编码分别是 97122。因此,如果要计算一个小写字母出现的次数,可以使用一个长度为 26 的数组来记录每个字母出现的次数,这个数组的下标对应着字母在 ASCII 编码中的编号减去字母 a 在 ASCII 编码中的编号,即 c - ‘a’。这个表达式的值就是数组中该字母出现的次数,然后再将其加 1。例如,‘c’ - ‘a’ 的结果是 2,所以 cnt[2]++ 就是计算字符 ‘c’ 出现的次数。

C写法:

//第一种解法:
#include <stdio.h>

int main() {
    int cnt[26] = {0}; // 初始化数组,计数器全部置为 0

    int c;
    while ((c = getchar()) != EOF) { // 读入字符,直到文件结束
        cnt[c - 'a']++; // 将计数器加一
    }

    for (int i = 0; i < 26; i++) {
        printf("%d ", cnt[i]); // 输出每个字母出现的次数
    }

    return 0;
}
//第二种解法:
#include <stdio.h>

int main() {
    int cnt[26] = {0}; // 初始化数组,计数器全部置为 0

    char c;
    while (scanf("%c", &c) != EOF) { // 读取字符,直到文件结束
        if (c >= 'a' && c <= 'z') { // 判断字符是否为小写字母
            cnt[c - 'a']++; // 将计数器加一
        }
    }

    for (int i = 0; i < 26; i++) {
        printf("%d ", cnt[i]); // 输出每个字母出现的次数
    }

    return 0;
}

Tips:

  1. getchar() 是标准 C 库中的一个函数,用于从标准输入流中读取下一个字符。它的函数原型为:

    int getchar(void);
    getchar() 函数返回读取到的字符的整数编码。例如,如果输入了字符 ‘a’,那么 getchar() 函数将 返回 ASCII 码值为 97。
    由于 getchar() 函数每次只能读取一个字符,因此在读取一行字符串时通常需要多次调用该函数,将每个字符逐个读取并存储到一个字符数组中,直到遇到换行符为止。
    注意,在读取完最后一个字符之后,输入流中可能会留下一个换行符,因此如果需要读取下一行字符串,可能需要在调用 getchar() 函数之前使用 getchar() 或 scanf() 函数读取并丢弃这个换行符。

  2. %c 是 scanf() 函数格式控制字符串中的一个转换说明符,用于读取输入流中的单个字符。它可以接受任何字符,包括空格、制表符和换行符。

    除了 %c 之外,常见的 scanf() 转换说明符还包括:

    %d 读取一个整数。
    %f 读取一个浮点数。
    %s 读取一个字符串。
    %u 读取一个无符号整数。
    %x 读取一个十六进制整数。
    %o 读取一个八进制整数。
    转换说明符可以搭配一些可选的修饰符,比如:

    表示该项读取的数据将不会被存储。
    h 表示读取一个短整数。
    l 表示读取一个长整数。
    ll 表示读取一个长长整数。
    n 表示读取到目前为止已经输入的字符数,可以将其存储在指定的变量中。
    例如,%d 和 %f 转换说明符就可以搭配修饰符 l 和 ll 来表示读取长整数和长长整数,分别对应 %ld 和 %lld,而 %f 还可以使用修饰符 e 或 E 来表示科学计数法。具体的用法可以参考 C 标准库的文档。

  3. int cnt[26] = {0}; 是一个长度为 26 的整型数组,用于记录每个小写字母出现的次数,因为在 ASCII 码中,小写字母的编码是连续的,并且是从 97 开始的,因此数组的下标是从 0 开始到 25,共计 26 个,对应了 26 个小写字母。

    字符数组需要多开一位放 \0 的原因是因为字符串在 C/C++ 中是以 null 结尾的字符数组,也就是以 ASCII 码为 0 的字符 \0 结尾的,这个字符表示字符串的结束,用于判断字符串的长度等信息。因此,如果字符串的长度为 n,那么字符数组的长度就应该为 n+1,最后一位存放 \0。而在本题中,字符数组只是用来临时存储输入的字符串,不需要将其转换为字符串,因此不需要多开一位存放 \0

C++写法:

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

int main() {
    char s[100001];
    cin.getline(s, 100001);
    int cnt[26] = {0};
    int len = strlen(s);
    for (int i = 0; i < len; i++) {
        char c = s[i];
        if (c >= 'a' && c <= 'z') {
            cnt[c - 'a']++;
        }
    }
    for (int i = 0; i < 26; i++) {
        cout << cnt[i] << " ";
    }
    return 0;
}

Tips:

  1. strlen() 函数接收一个 const char* 类型的参数,即一个指向以空字符 ‘\0’ 结尾的字符数组(C 语言中的字符串)的指针,然后遍历该字符数组,直到遇到空字符为止,统计字符的个数,最后返回字符个数。
    例如,在以下的代码中,strlen() 函数会返回字符串 “hello” 的长度 5:
    const char* str = “hello”;
    size_t len = strlen(str); // len 的值为 5
    需要注意的是,传给 strlen() 函数的字符数组必须以空字符 ‘\0’ 结尾,否则 strlen() 函数的行为是 未定义的。另外,由于 strlen() 函数返回值的类型是 size_t,因此需要包含 头文件。

Python写法:

s = input()
cnt = [0] * 26
for c in s:
    if c.isalpha() and c.islower():
        cnt[ord(c) - ord('a')] += 1
print(' '.join(map(str, cnt)))

Tips:

  1. 在Python中,没有像C++和C语言那样的数组概念,但是Python有列表(list)和元组(tuple)等数据结构来存储多个数据。其中列表可以动态地增加和删除元素,因此可以实现和数组类似的功能。例如,用列表来存储一组整数:
    arr = [1, 2, 3, 4, 5]
  2. 在 Python 中,列表(list)可以视作一种类似于数组的数据结构,因此可以通过列表来实现对数组的基本操作。
  • 创建一个列表
    列表可以通过使用方括号 [ ],在其中用逗号 , 分隔元素来创建。

    例如,以下代码创建了一个包含三个元素的列表:

    my_list = [1, 2, 3]
    

获取列表长度
使用 len() 函数获取列表的长度。

例如,以下代码输出了列表 my_list 的长度:

   print(len(my_list))

访问列表元素
使用索引来访问列表元素,索引从0开始。

例如,以下代码输出了列表 my_list 的第二个元素:

    print(my_list[1])

修改列表元素
使用索引来修改列表元素。

例如,以下代码将列表 my_list 的第一个元素修改为10:

   my_list[0] = 10
    print(my_list)

添加元素
使用 append() 函数在列表的末尾添加一个元素。

例如,以下代码在列表 my_list 的末尾添加了元素 4:

   my_list.append(4)
   print(my_list)

删除元素
使用 del 语句删除指定位置的元素。

例如,以下代码删除了列表 my_list 的第二个元素:
del my_list[1]
print(my_list)
遍历列表
可以使用 for 循环遍历列表中的所有元素。

例如,以下代码遍历了列表 my_list 中的所有元素:

  for i in my_list:
    print(i)

列表切片
使用切片操作获取列表的子列表。

例如,以下代码输出了列表 my_list 的前三个元素:
print(my_list[0:3])
输出结果为:
[10, 2, 3]
列表排序
使用 sort() 函数对列表进行排序。
例如,以下代码对列表 my_list 进行排序:
my_list.sort()
print(my_list)
输出结果为:
[1, 2, 3, 4, 10]
3.
print(’ '.join(map(str, cnt)))
这行代码的作用是将列表 cnt 中的每个元素转换成字符串,并用空格将它们连接起来,最终输出为一个字符串。具体来说:

map(str, cnt) 的作用是将列表 cnt 中的每个元素转换成字符串类型,这里使用了 map 函数。
str 是 Python 内置函数,用于将指定的对象转换成字符串类型。

’ '.join() 的作用是将一个由字符串构成的列表(或可迭代对象)中的字符串元素连接起来,并以指定的字符串(这里是空格 ’ ')作为连接符,最终返回一个字符串。这里使用了字符串的 join 方法。
综合起来,这行代码的作用是将列表 cnt 中的每个元素转换成字符串,并用空格将它们连接起来,最终输出为一个字符串。
5. ord() 是一个Python内置函数,用于返回字符的Unicode编码值。在这个程序中,它用于计算输入字符的索引值,从而确定在cnt数组中的位置。

例如,ord(‘a’)返回97,ord(‘b’)返回98,以此类推。

PHP写法:

<?php
$s = trim(fgets(STDIN));
$cnt = array_fill(0, 26, 0);
for ($i = 0; $i < strlen($s); $i++) {
    $c = $s[$i];
    if (ctype_lower($c)) {
        $cnt[ord($c) - ord('a')]++;
    }
}
echo implode(' ', $cnt);
?>

Tips:

  1. Python和PHP中的ord()函数用于将字符转换为它的ASCII码值,而Java,C和C++使用的是直接转换为字符所对应的整数。因此在这些语言中,可以直接使用字符与整数类型进行运算,比如在C/C++中,可以将字符类型的变量和整数类型的变量进行运算,得到字符所对应的ASCII码值。

  2.  $ cnt = array_fill(0, 26, 0);
    

    这段代码是PHP中用来初始化一个长度为26的数组$cnt,数组中每个元素都被赋值为0。

    array_fill()函数的语法为:

    array_fill(start_index, num, value)

    start_index:必需。规定从哪里开始填充数组。

    num:必需。规定填充多少个元素。

    value:必需。规定要填充的值。

    在这里,$cnt = array_fill(0, 26, 0)
    将 $cnt 数组
    的索引从0开始填充26个元素,每个元素的值都是0。

<< 打卡
在这里插入图片描述

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值