C语言小白也能写出整数转换英文表示,只需掌握这个分治思想

学习工控知识,就来工控小新

农历十一月十一日 2024/1/ 9


往期推荐

2024年1月7日,每日花费一分钟练习C语言

2024年1月6日,每日花费一分钟练习C语言

每日一练

/ Daily Exercises

整数转换英文表示

将非负整数 num 转换为其对应的英文表示。

示例 1:

输入:num =123

输出:“One Hundred Twenty Three

题目分析

首先,让我们分析一下题目的要求。给定一个非负整数num,我们需要将其转换为其对应的英文表示。例如,如果num=123,那么输出应该是“One Hundred Twenty Three”。我们可以发现,这个问题有以下特点:

- 输入的整数范围是0到2^31-1,也就是说,最大需要的计数单词是billion:1000000000,十亿。

- 输出的英文表示需要遵循一定的规则,比如每三位数字为一组,每组之间用相应的单位词连接,如thousand,million,billion等;每组内部,百位数字后面跟hundred,十位和个位数字根据不同的情况用不同的单词表示,如one,two,three,ten,eleven,twelve,twenty,thirty等;每个单词之间用空格分隔,首尾不需要逗号或句号等标点符号。

- 输入的整数可能是0,这是一个特殊情况,需要单独处理,输出应该是“Zero”。

那么,如何用C语言实现这个功能呢?我们可以采用分治的思想,将一个大的数字分解为若干个小的数字,然后分别转换为英文表示,最后拼接在一起。具体的步骤如下:

- 定义一个函数,比如叫做numberToWords,它接受一个整数参数num,返回一个字符串指针,指向转换后的英文表示。

- 在函数中,首先判断num是否为0,如果是,直接返回“Zero”。

- 如果num不为0,那么我们可以将num分解为四个部分,分别表示billion,million,thousand和剩余的部分,用四个变量存储,比如billion=num/1000000000,million=(num-billion*1000000000)/1000000,thousand=(num-billion*1000000000-million*1000000)/1000,rest=num-billion*1000000000-million*1000000-thousand*1000。

- 对于每个部分,我们可以定义一个辅助函数,比如叫做convertThree,它接受一个小于1000的整数参数,返回一个字符串指针,指向该整数的英文表示。这个函数的实现可以参考以下的逻辑:

- 如果参数为0,返回空字符串。

- 如果参数大于0,小于20,返回对应的单词,比如1返回“One”,2返回“Two”,11返回“Eleven”等,这些单词可以用一个数组存储,方便查找。

- 如果参数大于等于20,小于100,返回对应的单词,比如20返回“Twenty”,30返回“Thirty”等,这些单词也可以用一个数组存储,方便查找。如果参数不是10的倍数,还需要在后面加上个位数的单词,比如21返回“Twenty One”,35返回“Thirty Five”等。

- 如果参数大于等于100,小于1000,返回对应的单词,比如100返回“One Hundred”,200返回“Two Hundred”等,这些单词可以用百位数的单词加上“Hundred”组成。如果参数不是100的倍数,还需要在后面加上十位和个位数的单词,比如123返回“One Hundred Twenty Three”,456返回“Four Hundred Fifty Six”等。

- 用一个字符串变量,比如叫做result,存储最终的英文表示。根据每个部分是否为0,决定是否将其转换后的英文表示加入到result中,以及是否加上相应的单位词,比如billion,million,thousand等。注意每个单词之间要加上空格,首尾不要加空格。

- 返回result。

程序展示

基于以上的分析,我们可以用C语言编写如下的程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义一些常量,表示不同的单位和范围
#define BILLION 1000000000
#define MILLION 1000000
#define THOUSAND 1000
#define ZERO "Zero"
#define SPACE " "

// 定义一些数组,存储不同的单词
char *oneToNineteen[20] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
char *twentyToNinety[8] = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
char *hundred = "Hundred";
char *billion = "Billion";
char *million = "Million";
char *thousand = "Thousand";

// 定义一个辅助函数,用来转换小于1000的整数为英文表示
char *convertThree(int num) 
{
    char *result = (char *)malloc(32 * sizeof(char)); // 分配一个足够大的空间,存储转换后的字符串
    result[0] = '\0'; // 初始化为空字符串
    if (num == 0) 
  { // 如果是0,直接返回空字符串
        return result;
    }
    if (num < 20)
  { // 如果小于20,直接返回对应的单词
        strcpy(result, oneToNineteen[num - 1]);
        return result;
    }
    if (num < 100) 
  { // 如果小于100,返回对应的单词,如果不是10的倍数,还要加上个位数的单词
        strcpy(result, twentyToNinety[num / 10 - 2]);
        if (num % 10 != 0) 
    {
            strcat(result, SPACE);
            strcat(result, oneToNineteen[num % 10 - 1]);
        }
        return result;
    }
    // 如果大于等于100,返回对应的单词,如果不是100的倍数,还要加上十位和个位数的单词
    strcpy(result, oneToNineteen[num / 100 - 1]);
    strcat(result, SPACE);
    strcat(result, hundred);
    if (num % 100 != 0) 
  {
        strcat(result, SPACE);
        strcat(result, convertThree(num % 100)); // 递归调用自身,处理十位和个位数
    }
    return result;
}


// 定义一个主函数,用来转换任意非负整数为英文表示
char *numberToWords(int num) 
{
    if (num == 0) 
  { // 如果是0,直接返回“Zero”
        return ZERO;
    }
    // 将num分解为四个部分,分别表示billion,million,thousand和剩余的部分
    int billionPart = num / BILLION;
    int millionPart = (num - billionPart * BILLION) / MILLION;
    int thousandPart = (num - billionPart * BILLION - millionPart * MILLION) / THOUSAND;
    int restPart = num - billionPart * BILLION - millionPart * MILLION - thousandPart * THOUSAND;
    char *result = (char *)malloc(256 * sizeof(char)); // 分配一个足够大的空间,存储最终的英文表示
    result[0] = '\0'; // 初始化为空字符串
    // 根据每个部分是否为0,决定是否将其转换后的英文表示加入到result中,以及是否加上相应的单位词
    if (billionPart != 0)
  {
        strcat(result, convertThree(billionPart));
        strcat(result, SPACE);
        strcat(result, billion);
    }
    if (millionPart != 0)
  {
        if (strlen(result) != 0)
    { // 如果result不为空,说明前面已经有了一些单词,需要在后面加上空格
      strcat(result, SPACE);
    }
    strcat(result, convertThree(millionPart));
    strcat(result, SPACE);
    strcat(result, million);
  }
  if (thousandPart != 0) 
  {
    if (strlen(result) != 0) 
    { // 如果result不为空,说明前面已经有了一些单词,需要在后面加上空格
      strcat(result, SPACE);
    }
    strcat(result, convertThree(thousandPart));
    strcat(result, SPACE);
    strcat(result, thousand);
    }
    if (restPart != 0) 
    {
      if (strlen(result) != 0) 
      { // 如果result不为空,说明前面已经有了一些单词,需要在后面加上空格
        strcat(result, SPACE);
      }
    strcat(result, convertThree(restPart));
    }
  return result;
}


// 主函数,测试用例
// 主函数,测试用例
int main() 
{
    int num; // 声明一个整数变量num
    char *result; // 声明一个字符串指针变量result
    printf("请输入一个整数:"); // 提示用户输入
    scanf("%d", &num); // 从键盘读取一个整数,并赋值给num
    result = numberToWords(num); // 调用numberToWords函数,将num转换为英文表示,并赋值给result
    printf("%d -> %s\n", num, result); // 输出num和result
    free(result); // 释放分配的空间
    return 0;
}



程序测试

这个程序是在VC6.0的环境下运行的,输出结果如下:


当然,这个程序还可以进行一些优化和扩展,比如可以将分配的空间大小根据实际情况动态调整,而不是固定的值,增加程序的效率和稳定性;也可以将num作为用户输入,而不是固定的值,增加程序的灵活性和通用性。


源代码获取

#软件下载通道#



我用夸克网盘分享了「20240109」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。

链接:https://pan.quark.cn/s/ff7c9130f7fd

(链接和提取码建议复制粘贴,手动输入容易出现错误)

#支持一下#

分享整理,测试发布不易 如果您方便的话可以帮忙点一下↓↓

谢谢大家!




下期题目

单词搜索

给定一个m x n二维字符网格 board 和一个字符串单词word。如果word存在于网格中,返回true;否则,返false。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。


点赞加关注,学习不迷路

微信公众号|工控小新

EPLAN电气绘图、TIA博图基础 、CAD、C语言教学、单片机基础、三菱PLC ... 每日持续更新中

#头条挑创作挑战赛#

举报
评论 0