美文网首页算法和数据结构
机试常用算法和题型-进制转换专题

机试常用算法和题型-进制转换专题

作者: DecadeHeart | 来源:发表于2020-04-25 15:59 被阅读0次

    使用sscanf将字符数组转为整型的办法

    #include <cstdio>
    #include <cstring>
    //手动去除逗号的办法
    void dispose(char a[])
    {
        char temp[15]={0};
        int pos=0;
        for(int i=0;i<strlen(a);i++)
            if(a[i]!=',')
                temp[pos++]=a[i];
        for(int i=0;i<strlen(a);i++)
            a[i]=temp[i];
    }
    /*
    使用string处理的办法,更简洁
    int dealStr(string str){
        //好办法!!
        while(str.find(',')!=string::npos){
            size_t pos=str.find(',');
            str.erase(pos,1);
        }
    
        //好函数
        return atoi(str.c_str());
    }
    */
    int main()
    {   
        char A[15],B[15];
        while(scanf("%s %s",A,B)!=EOF)
        {
            int a,b;
            dispose(A);
            dispose(B);
          //如何将字符数组转为输出成a,b整型
            sscanf(A,"%d",&a);
            sscanf(B,"%d",&b);
            printf("%d\n",a+b);
            memset(A,0,sizeof(A));
            memset(B,0,sizeof(B));
        }
        return 0;
    }
    

    字符串到整数

    #include <string>
    #include <cstdlib>
    //atoi和itoa在头文件cstdlib中
    
    //居然直接stoi就可以做到了!!
     int num=stoi(temp);
    
    int StringToInt(string str){
      return atoi(str.c_str());
    }
    //stream方法
    int str_to_int(const string &string_temp){
        int temp;
        stringstream stream(string_temp);
        stream>>temp;
        return temp;
    }
    

    整数到字符串(十进制转字符串)

    #include <string>
    #include <cstdlib>
    
    //相当于to_string
    string IntToString(int num){
      char str[100];
      //itoa()函数有3个参数:第一个参数是要转换的数字,第二个参数是要写入转换结果的目标字符串,第三个参数是转移数字时所用 的基数。在上例中,转换基数为10。10:十进制;2:二进制...
      return itoa(num,str,10);
    }
    //有相同效果!!sprintf,<cstdlib>
    //int sprintf(char *str, const char *format, ...)
    //format -- 这是字符串,包含了要被写入到字符串 str 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。format 标签属性是 %[flags][width][.precision][length]specifier,具体讲解如下:
        char s[5],n[5];
            sprintf(s,"%d",i);
            sprintf(n,"%d",i*9);
    //sstream相同效果
    #include <sstream>
    stringstream ss;
    string s;
    int a;
    ss << a;
    s = ss.str();
    
    #include <cstdio>
    #include <cstring>
    int main()
    {
        char s[4],n[4];
        for(int i=100;i<=999;i++)
        {
            for(int j=100;j<=999;j++)
            {
                if(i+j==532)
                {
                  //将整数问题转为输出字符的问题,就很棒
                    sprintf(s,"%d",i);
                    sprintf(n,"%d",j);
                    if(s[1]==n[0]&&s[2]==n[1]&&s[2]==n[2])
                        printf("%c %c %c\n",s[0],s[1],s[2]);
                }
            }
        }
        return 0;
    }
    
    //sstream版整型到字符串
        stringstream sstream;
        string strResult;
        int nValue = 1000;
     
        // 将int类型的值放入输入流中
        sstream << nValue;
        // 从sstream中抽取前面插入的int类型的值,赋给string类型
        sstream >> strResult;
     
        cout << "[cout]strResult is: " << strResult << endl;
        printf("[printf]strResult is: %s\n", strResult.c_str());
    
    //to_string版本
    to_string的头⽂件是 #include <string> , to_string最常⽤的就是把⼀个int型变量或者⼀个数字转
    化为string类型的变量,当然也可以转double、 float等类型的变量,这在很多PAT字符串处理的题⽬
    中很有⽤处,以下是示例代码:
    

    十进制转其他进制

    #include <string>
    #include <cstdlib>
    
    string DecToOther(int dec){
      char str[100];
      return itoa(dec,str,16);
      //十进制转十六进制保存在str中
    }
    
    string decToString(int n){
        string str;
        while(n!=0){
            char c=(n%2)+'0';
            str=c+str;
            n=n/2;
        }
        return str;
    }
    
    #include <stdio.h> 
    main() 
    {  
      int a = 0 ; 
      printf ("Please enter a decimal number:") ; 
      scanf ("%d",&a) ; 
      //更简单办法
      printf ("%d's octal number is %o\n",a,a) ; 
    }
    

    其他进制转十进制,strtol最容易搞忘

    #include <string>
    #include <cstdlib>
    
    int OtherToDec(string str){
      const char *s=str.c_str();
      char *stop;
      return strtol(s,&stop,8);
      //8进制转十进制
    }
    //八进制转十进制
    
    int otherToDec(string str){
        int num=0;
        int len=str.size();
        for(int i=len-1;i>=0;i--){
            num=num+(str[i]-'0')*pow(2,len-1-i);
        }
        return num;
    }
    

    任意进制函数转换

    #include <iostream>
    #include <cstdlib>
    #include <string>
    using namespace std;
    
    int OtherToDec(string str,int n){
        const char *s=str.c_str();
        char *stop;
        return strtol(s,&stop,n);
    }
    string DecToOther(int dec,int m){
        char str[100];
        return itoa(dec,str,m);
    }
    int main()
    {
        int m,n;
        string  inputStr;
        while(cin>>n>>inputStr>>m){
            int temp=OtherToDec(inputStr,n);
            string ans;
            ans=DecToOther(temp,m);
            cout<<ans<<endl;
        }
    }
    

    strtol和itoa配合使用转换实例

    /*给出两个不大于65535的非负整数,判断其中一个的16位二进制表示形式,是否能由另一个的16位二进制表示形式经过循环左移若干位而得到。 循环左移和普通左移的区别在于:最左边的那一位经过循环左移一位后就会被移到最右边去。比如: 1011 0000 0000 0001 经过循环左移一位后,变成 0110 0000 0000 0011, 若是循环左移2位,则变成 1100 0000 0000 0110*/
    
    #include <iostream>
    #include <bits/stdc++.h>
    using namespace std;
    
    string decToString(int n){
    
        char str[100];
        //这个基数是目标
        return itoa(n,str,2);
    }
    
    int otherToDec(string str){
        char *stop;
        //基数搞错了,基数指的是当前
        return strtol(str.c_str(),&stop,2);
    }
    
    int main()
    {
        int n;
        while(cin>>n){
            int m;
            cin>>m;
            string str=decToString(n);
            while(str.size()<16){
               str='0'+str;
            }
            str=str+str;
            vector<string> ans;
            //这样循环就不会包括100了!!
            for(int i=1;i<16;i++){
                string temp=str.substr(i,16);
                ans.push_back(temp);
            }
            bool flag=false;
            for(int i=0;i<ans.size();i++){
                int temp=otherToDec(ans[i]);
                if(m==temp){
                    flag=true;
                    break;
                }
            }
    
            if(flag)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
        return 0;
    }
    

    strtol函数用法

    long int strtol(const char *str, char **endptr, int base)
    str -- 要转换为长整数的字符串。
    endptr -- 对类型为 char* 的对象的引用,其值由函数设置为 str 中数值后的下一个字符。
    base -- 基数,必须介于 2 和 36(包含)之间,或者是特殊值 0。
      #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
       char str[30] = "2030300 This is test";
       char *ptr;
       long ret;
    
       ret = strtol(str, &ptr, 10);
       printf("数字(无符号长整数)是 %ld\n", ret);
       printf("字符串部分是 |%s|", ptr);
    
       return(0);
    }
    数字(无符号长整数)是 2030300
    字符串部分是 | This is test|
    

    手工完成其他进制转十进制,十进制转其他进制

    #include <iostream>
    #include <string>
    using namespace std;
    int main(){
        int a,b;
        string str;
      //在这里使用c输入时
     // wh i l e ( s c an f ( " %d%s%d " , &a , s t r , &b ) ! = EOF ) {
        while(cin>>a>>str>>b){
    
            int tmp=0,c=1,lenth=str.size();
    
            for(int i=lenth-1;i>=0;i--){
                int x;
                //计算该位数字
                if(str[i]>='0'&&str[i]<='9'){
                    x=str[i]-'0';
    
                }
                else if(str[i]>='a'&&str[i]<='z'){
                    x=str[i]-'a'+10; //多想了。。a代表的是10
                }
                else{
                    x=str[i]-'A'+10;
                }
                tmp=tmp+x*c;
                c=c*a;
            }
    
            string ans;
            int size=0;
            do{
                int x=tmp%b;
                //计算当前位的数字
                ans[size++]=(x<10)?x+'0':x-10+'A';
                tmp=tmp/b;
            }while(tmp);
            //while后面加分号
            for(int i=size-1;i>=0;i--){
                cout<<ans[i];
            }
            cout<<endl;
        }
        return 0;
    }
    

    大数进制转换,大数除法

    #include <iostream>
    #include <string>
    using namespace std;
    int main(){
        int res[1000];
        string str;
    
        while(cin>>str){
            int len=str.size();
            int k=str.size();
            int num=0;
            while(len>0){
                res[num++]=(str[k-1]-'0')%2;
                //取余之后,得要模拟出除以2的效果!!
                int carry=0;
                for(int i=0;i<k;i++){
                    int s=((str[i]-'0')+10*carry)/2;
                    carry=(str[i]-'0')%2;
                    str[i]=s+'0';
                }
                //除法会产生位数减少
                while(str[k-len]=='0') len--;
            }
            for(int i=num-1;i>=0;i--) cout<<res[i];
            cout<<endl;
        }
        return 0;
    }
    //终极无敌循环班,m进制转n进制,大数,无限制
    #include <cstdio>
    #include <cstring>
    struct bign
    {
        int d[1000];
        int len;
        bign()
        {
            memset(d,0,sizeof(d));
            len=0;
        }
    };
    bign change(char s[])
    {
        bign a;
        a.len=strlen(s);
        for(int i=0;i<a.len;i++)
        {
            if(s[a.len-i-1]>='0'&&s[a.len-i-1]<='9')
                a.d[i]=s[a.len-i-1]-'0';
            else if(s[a.len-i-1]>='A'&&s[a.len-i-1]<='Z')
                a.d[i]=s[a.len-i-1]-'A'+10;
        }
        return a;
    }
    int main()
    {
        int m,n;
        while(~scanf("%d %d",&m,&n))
        {
            char a[1000]={'\0'};
            char out[1000]={'\0'};
            scanf("%s",a);
            bign b=change(a);
            int k=b.len,len=b.len,num=0;
            while(len>0)
            {
                int c=0;
                for(int i=len-1;i>=0;i--)
                {
                    int s=(b.d[i]+m*c)/n;
                    //终于明白了!!,c是循环计算,得出最后结果!!我傻了!!
                    c=(b.d[i]+m*c)%n;
                    b.d[i]=s;
                }
                if(c>=0&&c<=9)
                    out[num++]=c+'0';
                if(c>=10&&c<=36)
                    out[num++]=c+'a'-10;
                while(b.d[len-1]==0)
                    len--;
            }
            for(int i=num-1;i>=0;i--)
                printf("%c",out[i]);
            printf("\n");
        }
        return 0;
    }
    实际安排数字运用的范例
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    struct bign
    {
        int d[1010];
        int len;
        bign()
        {
            memset(d,0,sizeof(d));
            len=0;
        }
    }big[110];
    bign change(char s[])
    {
        bign a;
        a.len=strlen(s);
        for(int i=0;i<a.len;i++)
            a.d[i]=s[a.len-i-1]-'0';
        return a;
    }
    void trans(int a[],int n)
    {
        for(int i=0;i<n/2;i++)
        {
            int temp=a[i];
            a[i]=a[n-1-i];
            a[n-1-i]=temp;
        }
    }
    int main()
    {
        char s[1010];
        int mid[10010]={0},out[1010]={0};
        while(~scanf("%s",s))
        {
            bign c=change(s);
            int len=0;
            while(c.len>0)
            {
                int re=0;
              //关键是这个算法很棒!!,高位放在末尾,先动高位,高位除以成为0,可以直接删去
                for(int i=c.len-1;i>=0;i--)
                {
                    int temp=c.d[i]+re*10;
                    c.d[i]=temp/2;
                    re=temp%2;
                }
                mid[len++]=re;
                while(c.d[c.len-1]==0)
                    c.len--;
            }
            int sum=0;
            trans(mid,len);
            while(len>0)
            {
                int re=0;
                for(int i=len-1;i>=0;i--)
                {
                    int temp=mid[i]+re*2;
                    mid[i]=temp/10;
                    re=temp%10;
                }
                out[sum++]=re;
                while(mid[len-1]==0)
                    len--;
            }
            for(int i=sum-1;i>=0;i--)
                printf("%d",out[i]);
            printf("\n");
        }
        return 0;
    }
    

    另一种更为简单的描述,大数转换两次

    #include<iostream>
    #include<string>
    #define N 4000
    using namespace std;
    int conversion(int d[],int data[],int n,int x,int y){
        int size=0;
        for(int i=0;i<n;){
            int k=0;
            for(int j=i;j<n;j++){
                int t=(d[j]+k*x)%y;
                d[j]=(d[j]+k*x)/y;
                k=t;
            }
            data[size++]=k;
            while(d[i]==0) i++;
        }
        return size;
    }
    int main(){
        string s;
        int d[N],data[N];
        while(cin>>s){
            for(int i=0;i<s.length();i++)
                d[i]=s[i]-'0';
            int n=conversion(d,data,s.length(),10,2);
            int start;
            for(start=0;data[start]==0;start++);
            for(int i=start;i<n;i++)
                data[i-start]=data[i];
            n=conversion(data,d,n-start,2,10);
            for(int i=n-1;i>=0;i--)
                cout<<d[i];
            cout<<endl;
        }
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:机试常用算法和题型-进制转换专题

        本文链接:https://www.haomeiwen.com/subject/urjkwhtx.html