数位分离/数字反转/进制转换

· · 个人记录

一、数位分离

(一)明确位数的数位分离

例如:反向输出一个三位数

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,a,b,c;
    cin>>n;
    a=n%10;
    b=n/10%10;
    c=n/100;
    cout<<a<<b<<c;
    return 0;
}

(二)不明确位数的数位分离

1.分离过程

例如:n=12345

分离过程:

(1)n%10—>5,n=n/10 —>1234

(2)n%10—>4,n=n/10 —>123

(3)n%10—>3,n=n/10 —>12

(4)n%10—>2,n=n/10 —>1

(5)n%10—>1,n=n/10 —>0

观察上述过程会发现,一直重复做两件事,直到n=0停止 (1)求个位——n%10

(2)去除个位/缩小10倍——n=n/10

2.代码

#include<bits/stdc++.h> 
int main(){
    int n,a;
    cin>>n;
    while(n){
        a=n%10;
        n=n/10;
        cout<<a<<" ";
    } 
    return 0;
} 

二、数字反转

题目连接:

1.题目分析

例如:将12345(一万两千三百四十五)翻转,变成54321(五万四千三百二十一)

12345=1 * 10000+2 * 1000+3 * 100+4 * 10+5 * 1;

54321=5 * 10000+4 * 1000+3 * 100+2 * 10+1 * 1;
将上述写为:54321=((((0 * 10+5)* 10+4)* 10+3)* 10+2)* 10+1;

观察式子发现,数字反转过程中,需要将原数的每一位分离出来,并且不断扩大10倍。

2.分离及反转过程

(1)n%10—>5,s=s * 10+n%10=0 * 10+5 —>5,n=n/10 —>1234

(2)n%10—>4,s=s * 10+n%10=5 * 10+4 —>54 ,n=n/10 —>123

(3)n%10—>3,s=s * 10+n%10=54 * 10+3 —>543,n=n/10 —>12

(4)n%10—>2,s=s * 10+n%10=543 * 10+2 —>5432,n=n/10 —>1

(5)n%10—>1,s=s * 10+n%10=5432 * 10+1 —>54321,n=n/10 —>0

观察上述过程发现,一直重复做两件事,直到n=0停止

(1)求个位,将原数扩大10倍并累加当前个位——s=s * 10+n%10

(2)去除个位/缩小10倍——n=n/10

3.代码

#include<bits/stdc++.h> 
using namespace std;
int main()
{
    int n,s=0;
    cin>>n;
    while(n)
    {
        s=s*10+n%10;
        n=n/10;
    }
    cout<<s;
    return 0;
}

三、进制转换

(一)进制

1.进制概念

进位制是人们为了计数和运算方便而约定的记数系统,约定:

十进制满十进一,基数是10

二进制满二进一,基数是2

八进制满八进一,基数是8

十六进制满十六进一,基数是16 (数字不够,字母来凑。10-A,11-B,12-C,13-D,14-E,15-F)

结论:k进制满k进一,基数是k

2.位权

位权表示数字在某一位上所代表的权重;

例如十进制数字2156每一位数字的位权为,2的位权是1000,1的位权是100,5的位权是10,6的位权是1;

因此2156可以表示为,

2156=2 * 1000+1 * 100+5 * 10+6 * 1

观察下述几个式子

十进制:12345=1 * 10^4+2 * 10^3+3 * 10^2+4 * 10^1+5 * 10^0;

二进制:110011=1 * 2^5+1 * 2^4+0 * 2^3+0 * 2^2+1 * 2^1 +1 * 2^0;

八进制:7342=7 * 8^3+3 * 8^2+4 * 8^1+2 * 8^0;

结论:k进制下,每一位数字的位权与基数有关

(二)k进制转十进制

1.方法

每一位上的数 * 该位上的位权的积,再将所有积相加的和即为该数十进制下的表示。

例如:

二进制:110011=1 * 2^5+1 * 2^4+0 * 2^3+0 * 2^2+1 * 2^1 +1 * 2^0=51

八进制:7342=7 * 8^3+3 * 8^2+4 * 8^1+2 * 8^0=3810

那么该如何求每一位上的数字?如何让每一位数字乘以相应的位权再累加呢?

(1)求每一位数字:将k进制的数字看成十进制,模10求余数得每一位

(2)每一位数字乘以相应位权再累加:首先让分离出来的当前位 * 其相应位权,即s=s+n%10 * t(t表示位权);然后让位权t扩大k倍,即t=t * k

(3)令原数缩小10倍,即n=n/10

2.代码

//输入一个二进制数,输出其十进制的结果 
#include<bits/stdc++.h> 
using namespace std;
int main(){
    int n,s=0,t=1,k=2;//t是位权,k是基数 
    cin>>n;
    while(n){
        s=s+n%10*t;
        n=n/10;
        t=t*k;
    }
    cout<<s<<endl; 
    return 0;
} 

(三)十进制转k进制

1.方法

除k取余法:不断模k求余数,直到商为0停止,余数逆序组成k进制的数。

观察上述过程发现,重复做三件事,直到n=0停止


(1)求个位,将原数累加(当前个位 * 该位位权),即s=s+n%k * t

(2)位权扩大10倍,即t=t * 10

(3)去除个位/缩小k倍,即n=n/k

2.代码

//输入一个十进制数,输出其二进制的结果 
#include<bits/stdc++.h> 
using namespace std;
int main(){
    int n,s=0,t=1,k=2;//t是位权,k是基数 
    cin>>n;
    while(n){
        s=s+n%k*t;
        n=n/k;
        t=t*10;
    }
    cout<<s<<endl; 
    return 0;
}