猫儿恋上鱼 发表于 2021-5-4 14:17:26

有关离散数学的一道算法题求助大佬(我新手...)


老师布置的一个作业,不太懂要怎么弄,是要用字符数组一个一个遍历吗(感觉这样有点笨...)

人造人 发表于 2021-5-4 14:17:27

#include <stdio.h>
#include <ctype.h>

typedef struct {
    char first;
    char second;
} rule_t;

char enc_table;
char dec_table;

void rule_init(rule_t rule[], size_t size) {
    for(size_t i = 0; i < 256; ++i) {
      enc_table = dec_table = i;
    }
    for(size_t i = 0; i < size; ++i) {
      enc_table.first)] = enc_table[(int)rule.first] = rule.second;
      dec_table.second)] = dec_table[(int)rule.second] = rule.first;
    }
}

char *enc(char buff[], size_t size, const char *str) {
    for(size_t i = 0; ; ++i) {
      if(--size == 0) {buff = '\0'; break;}
      buff = enc_table[(int)str];
      if(str == '\0') break;
    }
    return buff;
}

char *dec(char buff[], size_t size, const char *str) {
    for(size_t i = 0; ; ++i) {
      if(--size == 0) {buff = '\0'; break;}
      buff = dec_table[(int)str];
      if(str == '\0') break;
    }
    return buff;
}

int main(void) {
    rule_t rule[] = {
      {'A', 'D'}, {'B', 'E'}, {'C', 'S'}, {'D', 'T'}, {'E', 'I'}, {'F', 'N'}, {'G', 'Y'}, {'H', 'A'}, {'I', 'B'},
      {'J', 'C'}, {'K', 'F'}, {'L', 'G'}, {'M', 'H'}, {' ', '+'}, {'N', 'J'}, {'O', 'K'}, {'P', 'L'}, {'Q', 'M'},
      {'R', 'O'}, {'S', 'P'}, {'T', 'Q'}, {'U', 'R'}, {'V', 'U'}, {'W', 'V'}, {'X', 'W'}, {'Y', 'X'}, {'Z', 'Z'},
      {'.', '-'}
    };
    rule_init(rule, sizeof(rule) / sizeof(rule));
    char buff;
    puts(enc(buff, 1024, "Good Friends in my eyes."));
    puts(dec(buff, 1024, "YKKT+NOBIJTP+BJ+HX+IXIP-"));
    return 0;
}


YKKT+NOBIJTP+BJ+HX+IXIP-
GOOD FRIENDS IN MY EYES.

猫儿恋上鱼 发表于 2021-5-4 14:20:41

图片在这

zsy1998 发表于 2021-5-4 15:41:58

本帖最后由 zsy1998 于 2021-5-4 16:04 编辑

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

int main() {
    char f = {0}, f_inv = {0};
    strcpy(f + 'A', "DESTINYABCFGHJKLMOPQRUVWXZ");
    f[' '] = '+';
    f['.'] = '-';
    for (int i = 0; i < 256; i++) {
      f_inv[(int)f] = i;
    }
    char s[] = "YKKT+NOBIJTP+BJ+HX+IXIP-";
    for (int i = 0; s; i++) {
      s = f_inv[(int)s];
    }
    printf("%s\n", s);
    return 0;
}

猫儿恋上鱼 发表于 2021-5-4 19:31:55

大佬们能讲下自己的思路吗,感觉有点懵逼啊..

猫儿恋上鱼 发表于 2021-5-4 19:32:55

人造人 发表于 2021-5-4 15:37


大佬能讲下思路吗...{:5_96:}

猫儿恋上鱼 发表于 2021-5-4 19:33:38

zsy1998 发表于 2021-5-4 15:41


讲下思路可以吗大佬...{:5_96:}

人造人 发表于 2021-5-4 19:42:07

猫儿恋上鱼 发表于 2021-5-4 19:32
大佬能讲下思路吗...

这该怎么讲呢,你哪里不明白吗?

人中仙 发表于 2021-5-4 22:14:14

猫儿恋上鱼 发表于 2021-5-4 14:20
图片在这

我没学过离散数学,这题我就用遍历的方法解决了。

#include <stdio.h>


int Decode(char *crypt_str,char *recipient);
int main(void){
    char test_str[] = "YKKT+NOBIJTP+BJ+HX+IXIP-";
    char decode_recipient;
    Decode(test_str,decode_recipient);
    printf("%s\n",decode_recipient);

    return(0);

}

int Decode(char *crypt_str,char *recipient){
    char CodeTable[] = "DESTINYABCFGH+JKLMOPQRUVWXZ-";
    while (*crypt_str != '\0'){
      for (int i = 0; i < 28; ++i) {          //遍历码表
            if(CodeTable == *crypt_str) {
                *recipient = (i > 13)?(i == 27 ? '.':'A'+i-1):(i == 13 ? ' ': 'A'+i);//嵌套三目运算符,将码表分为三个部分。
                ++recipient;
                break;
            }
      }
      ++crypt_str;
    }
    *recipient = '\0';      //添加结束符。
    return(0);
}

猫儿恋上鱼 发表于 2021-5-5 14:46:20

人造人 发表于 2021-5-4 19:42
这该怎么讲呢,你哪里不明白吗?

比如前几个函数的作用可以讲讲吗

人造人 发表于 2021-5-5 15:31:15

猫儿恋上鱼 发表于 2021-5-5 14:46
比如前几个函数的作用可以讲讲吗

rule_init 用来初始化 enc_table 和 dec_table 这两张表,一个用来加密,另一个是解密
enc 和 dec 这两个函数加密和解密字符串,通过查 enc_table,dec_table 这两张表

zsy1998 发表于 2021-5-5 16:09:02

猫儿恋上鱼 发表于 2021-5-4 19:32
大佬能讲下思路吗...

f是题目中的映射,就是A对应D,B对应E等等,也就是f['A']='D'。解码求f的逆映射f_inv,也就是D应该替换成A,E替换成B,也就是f_inv['D']='A',也就是f_inv]='A',这是9到11行求f_inv的思路,这块比较绕,要重点理解。
还有需要注意的是第5行将数组所有元素初始化为0了。第6行f本质是一个指针,加上'A'的ASCII码的偏移,这一行本质上等价于批量赋值,即f['A']='D',f['B']='E'等等。
页: [1]
查看完整版本: 有关离散数学的一道算法题求助大佬(我新手...)