无知的日记,继续追赶。

复数乘法器的功能实现(C语言)
题目介绍:
无知的日记,继续追赶。图片来源:LeetCode
这道题思路并不是很复杂,就是在对字符串处理上,步骤相对多一些。
人尽皆知,两个复数乘法的结果是:
二者实部之积与虚部之积的差 + 二者实部虚部之积的和*i。
所以现在我们的思路就清晰了:

  1. 求得以字符串形式给定的复数的实部虚部对应的整数,atoi函数完成这一步。(ASCII to integer,顾名思义,itoa同理)
    (字符串不能加减乘除,这时最终结果的实部虚部只能用整数乘法和加法运算出来)
  2. 将两部分——复数乘法最终结果的虚部和实部,再分别转换为两部分字符串
  3. 将两部分运算结果与’+'和’i’连接,成为最终结果。

最开始我提交的代码版本并没有itoa1函数模块,直接调用了头文件stdlib.h下的itoa函数(实现整数转字符串的功能),这一点在codeblocks的环境下是可以运行的,但是在力扣的编译环境下是不允许的,仅仅允许atoi,所以我就索性自己写了一个简陋版本的itoa函数.

char * itoa1(int n,char * d)
{
    char * zero=(char *)malloc(sizeof(char)*10);
    * zero = '0';
    *(zero+1)='\0';
    char * nega=(char *)malloc(sizeof(char)*100);
    * nega = '-';
    *(nega+1)='\0';
    int i,j;
    int k=1;
    int tem;
    if(n<0) tem=-n;
    else tem=n;
    int temtem=tem;
    while(tem)//求数字对应的最大位数,比如7888对应千分位
    {
        tem=tem/10;
         k*=10;
    }//这一步改变了tem的值,遂再用temtem保存tem的值
    for(i=k/10,j=0;i>0;i=i/10)//求abs(n)对应的字符串,使用强转并在ASCII码上位移以转到整数字符
    {
        * (d+j) = (char)(temtem/i %10) + 48;
        j++;
    }
    if(n<0) return strcat(nega,d);
        else if(n==0) return zero;
    else return d;
}
char * complexNumberMultiply(char * a, char * b){
    int i,j,Re_a,Re_b,Im_a,Im_b;
    char *c,*d;
    c = (char*)malloc(sizeof(char)*15);
    memset(c,'\0',sizeof(char)*15);
    d = (char*)malloc(sizeof(char)*15);
    memset(d,'\0',sizeof(char)*15);
    char  * t1;//四个字符串存两个实部两个虚部为atoi做准备
    char  * t2;
    char  * t3;
    char  * t4;
    t1 = (char*)malloc(sizeof(char)*10);
    t2 = (char*)malloc(sizeof(char)*10);
    t3 = (char*)malloc(sizeof(char)*10);
    t4 = (char*)malloc(sizeof(char)*10);
    memset(t1,'\0',sizeof(char)*10);
    memset(t2,'\0',sizeof(char)*10);
    memset(t3,'\0',sizeof(char)*10);
    memset(t4,'\0',sizeof(char)*10);


    for(i=0,j=0;*(a+i)!='+';i++,j++)//在取到'+'之前终止对t(i)的读取,下一步关于'i'同理
    {
        *(t1+j)=*(a+i);
    }
    int tem1=i;//要跳过字符位,i的值需要加1,下面一步取另一个复数的实部改变了i的值,先存起来。下面的tem2同理。
    for(i=0,j=0;*(b+i)!='+';i++,j++)
    {
        *(t2+i)=*(b+i);
    }//完成对实部的读取
    int tem2=i;
    Re_a=atoi(t1);
    Re_b=atoi(t2);
    for(i=tem1+1,j=0;*(a+i)!='i';i++,j++)//跳过字符位,读取虚部
    {
        t3[j]=*(a+i);
    }
    for(i=tem2+1,j=0;*(b+i)!='i';i++,j++)
    {
        t4[j]=*(b+i);
    }
    Im_a=atoi(t3);
    Im_b=atoi(t4);

    char * Add = (char*)malloc(sizeof(char)*2);
    * Add = '+';
    * (Add+1) = '\0';
    char * I = (char*)malloc(sizeof(char)*2);
    * I = 'i';
    * (I+1) = '\0';
    d = strcat(itoa1(Re_a*Re_b-Im_a*Im_b,d),Add);
    d = strcat(d,itoa1(Re_a*Im_b+Im_a*Re_b,c));
    d = strcat(d,I);
    free(t1);
    free(t2);
    free(t3);
    free(t4);
    free(c);

    return d;
}

结果:
无知的日记,继续追赶。

It sucks,innit?繁琐和低下的代码效率,占空间和运行时间都很大。
从未用过sprintf函数的我,因为strcat函数不能一数组和一指针同时处理,就重新定义了指针、初始化、连接。导致程序执行时间过长内存消耗大。这时候引入sprintf就好些了。
sprintf的功能极其强大,比如可以将整数打印在字符串上,大多数场合可以代替itoa函数。
优化后代码如下:

char * complexNumberMultiply(char * a, char * b){
    int i,j,Re_a,Re_b,Im_a,Im_b;
    char * c = (char*)malloc(sizeof(char)*15);
    memset(c,'\0',sizeof(char)*15);

    char  * t1;
    char  * t2;
    char  * t3;
    char  * t4;
    t1 = (char*)malloc(sizeof(char)*10);
    t2 = (char*)malloc(sizeof(char)*10);
    t3 = (char*)malloc(sizeof(char)*10);
    t4 = (char*)malloc(sizeof(char)*10);
    memset(t1,'\0',sizeof(char)*10);
    memset(t2,'\0',sizeof(char)*10);
    memset(t3,'\0',sizeof(char)*10);
    memset(t4,'\0',sizeof(char)*10);


    for(i=0,j=0;*(a+i)!='+';i++,j++)
    {
        *(t1+j)=*(a+i);
    }
    int tem1=i;
    for(i=0,j=0;*(b+i)!='+';i++,j++)
    {
        *(t2+i)=*(b+i);
    }
    int tem2=i;
    Re_a=atoi(t1);
    Re_b=atoi(t2);
    for(i=tem1+1,j=0;*(a+i)!='i';i++,j++)
    {
        t3[j]=*(a+i);
    }
    for(i=tem2+1,j=0;*(b+i)!='i';i++,j++)
    {
        t4[j]=*(b+i);
    }
    Im_a=atoi(t3);
    Im_b=atoi(t4);
    sprintf(c,"%d%s%d%s",Re_a*Re_b-Im_a*Im_b,"+",Re_a*Im_b+Im_a*Re_b,"i");
    free(t1);
    free(t2);
    free(t3);
    free(t4);

    return c;
}

效果还不错~就是太费内存。
无知的日记,继续追赶。

唉,当我在解决一个问题时,顺着自己的思路,不断花费时间试错,最后只得到一个勉强的结果,殊不知早有极其简洁优美屡试不爽的解决办法早已被别人设计,在等着我了。
这就是没好好学习的结果吧…>_<
无知的代价是可怕的,虽然探索的过程是愉悦的。
这件事,好坏参半吧…
继续前进哦,You gotta move and move on.
2020.12.28

上一篇:【Matlab 030期】【图像识别】银行卡号识别matlab源码


下一篇:用t-io从零写一个像微信的IM(05):架构设计