位数分离


大家好,这一篇博客讲的是我对 位数分离的理解。以下代码使用的是 VS2022环境下的 C语言,如果有错误,还请读者大大们指出。

位数分离

概念

这里的位数分离指的是:将一个数每个位数上的数字分离出来,进行操作。

在代码题中可能会用到这种方法,接下来我会通过例题和代码操作进行我个人对其的理解。

例题

1.求一个数的位数有几位(范围0 ~ 10^9)

#include <stdio.h>

int main()
{
	int n = 0;
	int num = 1; // 记录位数的变量
	scanf("%d", &n);

	int temp = n; // 利用临时变量接收
	while (temp /= 10)
		num++;

	printf("%d\n", num);
	return 0;
}

num变量 初始化为1是因为个位数在除以10后为0,在后面的 temp /= 10 等价于 temp = temp / 10,当temp为0时跳出循环,反之num++并再次进入循环去掉已被记录的位数,其只能记录十位数及以上的位数。用temp临时变量 来操作仅仅是我的个人习惯,这题可以直接用n来除以10。

2.输入一个数把每个位数上的数字加起来的和

这一题截取于牛客网的题目BC87 数位之和

#include <stdio.h>

int main()
{
	int n;
	scanf("%d", &n);
	int sum = 0; // 计算和
	for (int temp = n; temp; temp /= 10) // 位数分离
	{
		int a = temp % 10; // 将当前位数上的数保存
		sum += a; // 求和
	}
	printf("%d\n", sum);
	return 0;
}

这一题将位数分离用的while循环改为了for循环

3.在1到100中用代码统计有多少个数字9

此题要注意的是99有两个数字9

#include <stdio.h>

int main()
{
	int num = 0; // 记录此数出现的次数
	for (int i = 1; i < 100; i++) // 遍历1到99
	{
		for (int temp = i; temp; temp /= 10) // 对当前的数 位数分离
		{
			int a = temp % 10; // 保留当前位数上的数
			if (a == 9) // 记录为数字9的数
				num++;
		}
	}
	printf("%d\n", num);
	return 0;
}

4. 求输入一个数时将每个位数分离开输出(范围1 ~ 10^10)

例如:

输入:
12345
输出:
5
40
300
2000
10000

输入:
987654321
输出:
1
20
300
4000
50000
600000
7000000
80000000
900000000

#include <stdio.h>
#include <math.h>

int main()
{
	int n;
	scanf("%d", &n);
	for (int temp = n, i = 0; temp; temp /= 10, i++) // 将位数分离与次方i合并
	{
		int a = temp % 10; // 保留当前位数上的数
		printf("%d\n", a * (int)pow(10, i)); // 使用pow函数将每个数对应在自己的位数上
	}
	return 0;
}

通过上面的题目我们可以知道,使用位数分离在一些需要对自身位数上的数操作时的题目是一个不错的选择。那接下来我们去牛客网上寻找一些类似的题看能否实现。

5.水仙花数

这题取自于牛客网BC91 水仙花数

#include <stdio.h>

int main()
{
    int n, m;
    while (scanf("%d %d", &n, &m) == 2)
    {
        int exist = 0;
        for (int i = n; i <= m; i++) // 遍历n到m中的数
        {
            int sum = 0; // 保存立方和
            for (int temp = i; temp; temp /= 10) // 位数分离
                sum += (temp % 10) * (temp % 10) * (temp % 10);
            if (i == sum) // 判断是否相等
                exist = printf("%d ", sum);
        }
        if (!exist) // 不存在的情况
            printf("no");
    }
    return 0;
}

水仙花数这一经典题也可以使用位数分离。

6.变种水仙花

这题取自于牛客网BC92 变种水仙花

#include <stdio.h>
#include <math.h>

int main()
{
    for (int i = 1e4; i < 1e5; i++)
    {
        int sum = 0;
        for (int j = 1; j <= 4; j++)
        {
            int left = i / (int)pow(10, j); // 将左半分离
            int right = i % (int)pow(10, j);  // 将右半分离
            sum += left * right; // 计算两者的乘积
        }
        if (i == sum)
            printf("%d ", i);
    }
    return 0;
}

通过观察发现上式pow函数与j次方可以用j = 10, j *= 10来替换,还可以把right和left计算的过程直接放在sum计算中,则可以这样写:

#include <stdio.h>

int main()
{
    for (int i = 1e4; i < 1e5; i++)
    {
        int sum = 0;
        for (int j = 10; j <= 1e4; j *= 10)
            sum += (i / j) * (i % j); // 计算两者的乘积
        if (i == sum)
            printf("%d ", i);
    }
    return 0;
}

7.回文对称数

这题取自于牛客网BC97 回文对称数

#include <stdio.h>

int main()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        for (int i = 1; i <= n; i++)
        {
            int sum = 0;
            for (int temp = i; temp; temp /= 10)//将原来的数 倒置
                sum = sum * 10 + temp % 10 ;
            if (i == sum) // 判断
                printf("%d\n", i);
        }
    }
    return 0;
}

8.打印自幕数(1~10^6)

#include <stdio.h>
#include <math.h>

int main()
{
	for (int i = 1; i <= 1e6; i++)
	{
		int sum = 0;
		int n = 0;
		for (int temp = i; temp; temp /= 10) // 计算位数
			n++;
		for (int temp = i; temp; temp /= 10) // 当前位数的幕
			sum += (int)pow((temp % 10), n);
		(i == sum) ? printf("%d ", i) : 0; // 打印
	}
	return 0;
}

9.十与十以内进制的任意转换

描述:
输入一个十进制的数(1~1000),再输入十以内的一个进制,将十进制的数转化为该进制并打印。
例如:
输入:
10
2
输出:
1010
输入:
9
9
输出:
10

#include <stdio.h>

int main()
{
	int n, num1;
	scanf("%d", &n);
	scanf("%d", &num1);
	int sum1 = 0;

	for (int temp = n, i = 1; temp; temp /= num1/*想要转化的进制*/, i *= 10/*当前进制*/)
		sum1 += temp % num1/*想要转化的进制*/ * i;

	printf("%d\n", sum1);
	return 0;
}

总结

使用位数分离时应该结合题目条件,要准备好位数分离的对象位数分离后的代码连接与配合

结语

以上是我对位数分离的理解,如果文章有错误还请联系我,我会更改的。

谢谢阅读

  • 20
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值