进制转换、字符串操、大数运算

C plus算法C plus约 1206 字大约 4 分钟...

提示

进制转换、字符串操、大数运算

进制转换、字符串操、大数运算

一、进制转换

1.1 itoa

char*itoa(int value,char*string,int radix);

int num = 10;  
char str[100];  
_itoa(num, str, 2);  //c++中一般用_itoa,用itoa也行,

1.2**sprintf()**函数

//(可以将一个10进制数转换为指定格式的n进制字符串)
int sprintf( char *buffer, const char *format, [ argument])

char s[100]={0};
sprintf(s, "%d", 123); //十进制输出产生"123"
sprintf(s, "%4d%4d", 123, 4567); //指定宽度不足的左边补空格,产生:" 1234567"
sprintf(s, "%8o", 123);    //八进制输出,宽度占8个位置
sprintf(s, "%8x", 4567); //小写16 进制,宽度占8 个位置,右对齐
sprintf(s, "%10.3f", 3.1415626); //产生:" 3.142"
int i = 100;
sprintf(s, "%.2f", i);    //注意这是不对的
sprintf(s, "%.2f", (double)i);    //要按照这种方式才行

1.3 字符串流string,streamopen in new window

string s="20";
int a;
stringstream ss;
ss<<hex<<s;    //以16进制读入流中
ss>>a;        //10进制int型输出

string s1,s2;
int a=30;
stringstream ss;
ss<<oct<<a;        //10进制转成八进制读入流中,再以字符串输出
ss>>s1;            
cout<<s1<<endl;        //输出:36
ss.clear();        //不清空可能会出错。
ss<<hex<<a;         //10进制转成十六进制读入流中,,再以字符串输出
ss>>s2;            
cout<<s2<<endl;        //输出:1e

cout << "36的8进制:" << std::oct << 36 << endl;
cout << "36的10进制" << std::dec << 36 << endl;
cout << "36的16进制:" << std::hex << 36 << endl;
cout << "36的2进制: " << bitset<8>(36) << endl;

1.4 十进制转2进制方法

vector<int> Transform(int n)
{
    vector<int>m;
    for(int i =31; i>=0; i--)
    {
        m.push_back( ( (n>>i) & 1) );//与1做位操作,前面位数均为0
        //cout<<(n);//输出二进制
    }
    return m;
}

二、字符串转数字

//使用stoi()
string s("12345");
long long a = stoi(s);

//使用atoi()
char str3[10] = "3245345";
//数字简单,所以转数字一个参数 
long long a = atoi(str3);

//使用 sscanf() 映射
long long c = 0;
char str5[10] = "661234544";
sscanf(str5, "%d", &c); //从左至右,字符串转数字

//自定义
void myatoi(char str[], int &num)
{
    int i = 0;
    int temp = 0;
    while (str[i] != '\0')
    {
        temp=temp*10+(str[i++]-'0');
    }
    num=temp;
}

三、数字转字符串

//to_string()
long long m = 1234566700;
string str = to_string(m);   //系统提供数字转字符

//itoa()
int n = 100;
char str2[10];
//字符串比较麻烦,所以转字符串三个参数,我是这么记得(手动滑稽) 
itoa(n,str2,10); //第一个参数为整数,第二个为字符串(char*),第三个为进制 

//sprintf() 映射
long long b = 1234560;
char str4[10] = {0};
sprintf(str4, "%d", b); //从右至左,把数转换为字符串

数字逐位放入vector

void privec(vector<int> vec)
{
    for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}
int numTovec(int a,int b){
    //#include<string>
    string stra = to_string(a);   //系统提供数字转字符
    string strb = to_string(b);   //系统提供数字转字符

    vector<int> numa(stra.size(),0);
    vector<int> numb(strb.size(),0);

    for(auto ch:stra){
        numa.push_back(ch-'0');
    }
    privec(numa);
    for(auto ch:strb){
        numb.push_back(ch-'0');
    }
    privec(numb);
    return 0;
}

四、精度控制

4.1 利用字符串改变数字位数

float abc=1.28837;
string str=to_string(abc);
cout<<str<<endl;
str.resize(3);

4.2利用字符串流

char s[100]={0};
sprintf(s, "%.2f", 1234.765); //十进制输出产生"1234.77"
cout<<s<<endl;
sprintf(s, "%.2f", double(123)); //十进制输出产生"123.00"
cout<<s<<endl;

//#include <sstream> 
//#include <iomanip>
float fnum=1.2456;
stringstream ss; 
ss << fixed << setprecision(5) << fnum; 
ss >> fnum; 
cout<<fnum<<endl;

五、大数运算

5.1 乘法

#include<iostream>
#include<vector>
#include<deque>
#include<sstream>
using namespace std;

std::string BigNumMultiply(std::string s1, std::string s2)
{
    //记录最终结果
    std::string res = "";
    //使用deque是因为出现进位时可以在队列前插入数据,效率比vector高,大小设为最小
    //两个数相乘的结果肯定会比两个数的位数之和小:99*99<100*100<6位数,那就是5位数
    std::deque<int> vec(s1.size() + s2.size() - 1, 0);

    //s1=125
    //s2=25
    //正常算法
    //      1  2  5
    //         2  5
    //-----------------
    //           25
    //          10
    //          5
    //          10
    //          4
    //         2
    //         3125
    //倒序乘法
    //vec 0 0 0 0 0 0 0 0 0 
    //vec:2 5
    //vec:  4 10 
    //vec:    10 25
    //vec:2 9 20 25

    for (int i = 0; i < s1.size(); ++i)
    {
        for (int j = 0; j < s2.size(); ++j)
        {
            //第0个数相乘,错0位,第1个数相乘错1位
            vec[i + j] += (s1[i] - '0') * (s2[j] - '0'); //记录相乘结果
        }
    }
    //进位处理
    int addflag = 0;
    //倒序遍历,是因为最左边的值为最高位,最右边的值在最低位,进位运算要从低位开始
    for (int i = vec.size() - 1; i >= 0; --i)
    {
        int temp = vec[i] + addflag; //当前值加上进位值
        vec[i] = temp % 10;          //当前值
        addflag = temp / 10;         //进位值
    }
    
    //看最后一位有没有进位,如果有进位,将进位加到队列头部
    while (addflag != 0)
    {
        int t = addflag % 10;
        vec.push_front(t);
        addflag /= 10;
    }

    for (auto c : vec)
    {
        std::ostringstream ss;
        ss << c;
        res = res + ss.str();
    }
    return res;
}

int main()
{
    std::string str1="125",str2="25";
    //while (std::cin >> str1 >> str2)
    //{
        std::cout << str1 << "*" << str2 << "=" << std::endl;
        std::cout << BigNumMultiply(str1, str2) << std::endl;
    //}
    return 0;
}
已到达文章底部,欢迎留言、表情互动~
  • 赞一个
    0
    赞一个
  • 支持下
    0
    支持下
  • 有点酷
    0
    有点酷
  • 啥玩意
    0
    啥玩意
  • 看不懂
    0
    看不懂
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.2