一个整数使用英文表达的字母计数

  • 题目:

把1到5写成英文单词分别是:one、two、three、four、five。这些单词一共用了3+3+5+4+4 = 19 个字母。

如果把1到1000都写成英文单词,一共要用多少个字母?

注:不计入空格和连字符,例如,342,three hundred and forty-two, 包含23哥字母,而115(one hundred and fifteen)包含20个字母。单词"and" 的使用方式遵循英式英语的规则。

  • 题目分析

通过题目描述,我们可以知道这是一个枚举问题,但是从1~1000逐个枚举,显然不是题目的目的,枚举也是有技巧的,有规律可循的,我们的任务就是找到其中的规律。

|----|-------|----|----------|----|--------------|----|--------------|
| | | | | 20 | twenty | 30 | thirty |
| 1 | one | 11 | eleven | 21 | twenty-one | 31 | thirty-one |
| 2 | two | 12 | twelve | 22 | twenty-two | 32 | thirty-two |
| 3 | three | 13 | thirteen | 23 | twenty-three | 33 | thirty-three |
| 4 | four | 14 | fourteen | 24 | twenty-four | 34 | thirty-four |
| 5 | five | 15 | fifteen | 25 | twenty-five | 35 | thirty-five |
| 6 | six | 16 | sixteen | 26 | twenty-six | 36 | thirty-six |
| 7 | seven | 17 | seveteen | 27 | twenty-seven | 37 | thirty-seven |
| 8 | eight | 18 | eighteen | 28 | twenty-eight | 38 | thirty-eight |
| 9 | nine | 19 | nineteen | 29 | twenty-nine | 39 | thirty-nine |
| 10 | ten | | | | | | |

通过这个表格可以看到,1~19 的英文单词是没有规律的,但是21~29, 31~39 是有规律的,分别是20 + 1~9, 30+1~9,以此类推,41~49,51~59 ,直到91~99,都是对应的十位数加上个位数,这似乎就是一个规律了。

我们总结一下:

定义一个函数f(n), 求n用英文表示以后所需要的字母个数,则有如下情况:

  1. 当n < 20 时, f(n) 可以通过查表求得;

  2. f(21) = f(20) + f(1), f(37) = f(30) + f(7), f(92) = f(90) + f(2);

  3. 当n < 100 时, 通过下列结果的值,可求出此范围内其他结果的值:

f(1) , f(2), f(3), f(4), f(5), f(6), f(7), f(8), f(9), f(10), f(11), f(12), f(13), f(14), f(15), f(16), f(17), f(18), f(19), f(20), f(30), f(40), f(50), f(60), f(70), f(80), f(90);

  1. 为了计算方便,规定f(0) = 0;

  2. 当任意给定一个数字n , 20 <= n <= 100 ,

获得十位上的数:m = n /10 ;获得 个位上的数: l = n % 10;

所以: f(n) = f( m* 10) + f(l)。

  1. 当n >= 100 时,

获得百位上的数:h = n / 100 ;

获得十位 和 个位 上的数:m = n % 100

f(n) = f(h) + 8(hundred) + 3(and) + f(m);

Tip:卖个关子,这里为什么将十位和个位上的数字需要整体处理? 谜底见代码实现部分。

分析到这里,我们来想想需要多少个数据结构来存储固定数据值:

arr1 用于存放0~19: int arr1[20] = {}

arr2 用于存放整十 数值(20,30,30,40,50,60,70,80,90): int arr2[9] = {}

data1 用于表示"and";

data2 用于表示"hundred"

data3 用于表示 "one thousand"

  • 代码实现:
cpp 复制代码
   #include <stdio.h>
   #define HUNDRED 7
   #define ONE_THOUSAND 11
   #define AND 3
   int get_letters(int n){
       static int arr1[20] = {0, 3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8};
       static int arr2[10] = {0,0,6,6,5,5,5,7,6,6};
  
       if(n < 20) return arr1[n];
      if(n < 100){
          return arr2[n/10] + arr1[n%10];
      }
      if(n < 1000){
          if(n % 100 == 0) return arr1[n/100]+ HUNDRED;
          return arr1[n/100]+HUNDRED + AND +  get_letters(n%100);
      }
 
      return ONE_THOUSAND;
  }
 
  int main(){
      int sum = 0;
      for(int i = 1; i <= 1000;i++){
          sum += get_letters(i);
      }
      printf("sum = %d\n",sum);
      return 0;
 }
  • 运行结果:
  • 分析总结:
  1. 这道题目比较简单,但是训练了我们的计算机思维以及规律总结能力;

  2. 思考3个问题:

1) 为什么函数get_letters 中的arr1 和arr2 要定义为static?

2) 函数get_letters中的arr1[0], arr2[0], arr[1] 为什么要初始化为0?

3)在函数get_letters中递归调用get_letters 有什么好处?

答:

1)对于第一个问题,我们可以换一个问法,"为什么这段代码中将局部变量声明称为静态?",

首先,这是因为变量声明为静态它的初始化就只会进行一次,虽然多次调用了这个函数,但是对这个变量的初始化就只会在第一次调用时发生,因此,减少了内存分配和回收的开销,从而提高了程序的性能;

第二,声明为静态,这个局部变量的存储位置就由栈变为静态存储区,栈的空间是有限的,这样做节省了栈空间,

第三,声明为静态,虽然它的生命周期延长了,但是由于是局部变量,所以它的作用域还是受到限制的,仅限在这个函数内部, 所以避免了污染全局命名空间

2) arr1[0] = 0 , 这是因为arr1[0] 表示的是变量0, 但是我们操作的数据规模是1~1000, 这个值没有用到;

arr2[0] 表示一个数字的十位上0, arr2[1], 表示一个数字的十位上1, 但是经过分析英文单词的特点,已经将10~19 初始化到arr1 中,所以如果当前数字的十位上是0 或1 ,我们就去arr1去找对应的值,arr2 就从arr[2] 开始设置初始值。

3) 关于get_letters函数的递归调用,发生在处理当前数值是三位数的情况,并且是用于处理除去百位数后剩下的2位数, 因为剩下的两位数,又可以分为两种情况,即0~20 和20~99, 所以此时用递归调用,将待处理数据直接传入函数,减少了代码分析的难度,使逻辑分析更清楚,也避免了代码出错的概率。

相关推荐
林的快手24 分钟前
209.长度最小的子数组
java·数据结构·数据库·python·算法·leetcode
千天夜33 分钟前
多源多点路径规划:基于启发式动态生成树算法的实现
算法·机器学习·动态规划
从以前39 分钟前
准备考试:解决大学入学考试问题
数据结构·python·算法
.Vcoistnt1 小时前
Codeforces Round 994 (Div. 2)(A-D)
数据结构·c++·算法·贪心算法·动态规划
ALISHENGYA1 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(实战训练三)
数据结构·c++·算法·图论
我码玄黄4 小时前
正则表达式优化之算法和效率优化
前端·javascript·算法·正则表达式
Solitudefire4 小时前
蓝桥杯刷题——day9
算法·蓝桥杯
三万棵雪松5 小时前
1.系统学习-线性回归
算法·机器学习·回归·线性回归·监督学习
Easy数模5 小时前
基于LR/GNB/SVM/KNN/DT算法的鸢尾花分类和K-Means算法的聚类分析
算法·机器学习·支持向量机·分类·聚类
2401_858286115 小时前
117.【C语言】数据结构之排序(选择排序)
c语言·开发语言·数据结构·笔记·算法·排序算法