比较笨的方法,只会用一点点哈希。

哈希的特点就是费时间,不过体积用的少,超过了94%的代码。

将字母转换为索引,出现过的字母的标志位可以被置位,这样可以区别出字母表中的密钥和非密钥。

按照密钥顺序将字母填入密码表,因为要求是不能重复填入,所以在密钥中字母出现过一次之后,可将其标志位复位,视同没出现过的字母,这样在第二次出现时方可不写入密码表。

再次置位密钥。

未出现过的字母仍为初始状态,可以此为标志将剩余字母填入密码表。

然后在密码表中查找对应明文即可获得密文。

#include<stdio.h>
#include<string.h>


int i=0,j=0,k=0,len_1,len_2,flag[26],len_3;
char key[100],line[100],new_key[26],key_list[26];
int list[26];


int main()
{
    
    scanf("%s\n",&key);
    scanf("%s\n",&line);
    
    len_1=strlen(key);//密钥
    len_3=strlen(line);//明文
   
    
    memset(list, 0, sizeof(int)*26);//字母表置0
    
    for(i=0;i<len_1;i++)
    {
        list[key[i]-'a']=1;//处理密钥,密钥中出现过的字母对应索引置1
    }
    
    memset(flag,0,sizeof(int)*26);
    for(i=0;i<len_1;i++)//密码表前部分
    {
        
        if(list[key[i]-'a']==1)
        {
        key_list[k]=key[i];//按顺序将密钥中出现过的字母放入密码表
        list[key[i]-'a']=0; //去除重复出现的密钥中的字母,将其阻挡于密码表生成流程之外
        k++;
        }
        
        
    }
   
     len_2=k;
    
    for(i=0;i<len_1;i++)//回溯密钥中出现过的密码表
    {
        list[key[i]-'a']=1;
    }
    
     
    
    for(i=0;i<26;i++)//密码表后部分
    {
        
      if(list[i]==0)  //密钥中没有出现过的字母对应之索引与出现过的不同
      {
        key_list[j+len_2]=i+'a';//将剩余字母按正常字母表顺序填入密码表
        j++;
      }
      
    }
    
    for(i=0;i<len_3;i++)//明文转换为密文,按序输出
    {
    printf("%c", key_list[line[i]-'a']);
        
        
    }
    
    
    
}