陈十七52Hz 2022-07-28 10:08 采纳率: 100%
浏览 69
已结题

怎么用c语言通过关键词生成随机的短小句子

我最近想做一个代码练习,怎么样才能用C语言 把几个关键词结合生成短小的句子?
这样的也行
词0(变量或不选择)词1(随机或不选择)+词2(随机或不选择)+词3(随机或不选择)+词4(变量或不选择)
如果能够更通顺些就更好不过了
有酬金 越是通顺,精巧 越好
请把代码过程 贴出来,谢谢

  • 写回答

4条回答 默认 最新

  • 关注

    我大概做了个简单的模型,能大致的实现
    我是采用Liunx+gcc做的,vs或dev可能不能用。如有关于dev的问题,欢迎评论或私聊
    我使用了三个文件,把这三个文件放在一个目录里
    文件一:words.h

    
    ```c
    /*words.h*/
    #ifndef _WORDS_H_
    #define _WORDS_H_
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    // 每个词集的大小
    // 可以以后修改以扩大数组
    #define WORDS_SIZE 4
    
    typedef char word[16]; // 给字符串起别名word
    
    // 定义语法结构体
    typedef struct {
        size_t size; // 词的数量
        word point;  // 语法的具体描述
    } point_t;
    
    extern word n[WORDS_SIZE];     // 声明名词集(数组)
    
    extern word v[WORDS_SIZE];     // 声明实义动词集
    
    extern word model_v[WORDS_SIZE]; // 声明情态动词集
    
    extern word pron_sub[WORDS_SIZE]; // 声明代词主语形式集
    
    extern word pron_obj[WORDS_SIZE]; // 声明代词宾语形式集
    
    extern point_t points[WORDS_SIZE];  // 声明语法集
    
    // 自定义一个布尔枚举
    typedef enum {False, True} c_bool;
    
    // 自定义词性枚举
    //           名  动 情态 代词主语 代词宾语 the 
    typedef enum {N, V, MV,   PS,     PO,       T} word_type_t;
    
    // 函数声明
    
    // 判断数组里是否有指定元素
    c_bool is_in_array(word arr[], word w);
    
    // 生成随机数
    int get_random(int max);
    
    // 从数组里随机取出成员
    char *get_random_array(word arr[]);
    
    // 获取一个词的词性
    word_type_t get_words_type(word w);
    
    // 将以字符形式存储的词性转换为word_type_t
    word_type_t char2word_type(char t);
    
    // 随机生成指定词性的词
    char *get_random_type(word_type_t type);
    
    #endif
    
    
    

    文件二:words.c

    
    ```c
    /*words.c*/
    #include "words.h"
    
    /*
    这块定义了词集。词集里的词越多,可以生成的句子变化就越多
    可以在words.h头文件里修改WORDS_SIZE的值以扩大数组
    */
    
    word n[WORDS_SIZE] = {
        "mouse", "computer", "Ctrl-c", "gun"
    };     // 名词集(数组)
    
    word v[WORDS_SIZE] = {
        "use", "make", "open", "bomb"
    };     // 实义动词集
    
    word model_v[WORDS_SIZE] = {
        "must", "should", "will", "would"
    }; // 情态动词集
    
    word pron_sub[WORDS_SIZE] = {
        "I", "you", "he", "she"
    }; // 代词主语形式集
    
    word pron_obj[WORDS_SIZE] = {
        "me", "you", "him", "her"
    }; // 代词宾语形式集
    
    // 规定语法集具体描述如下
    /*
    n:名词
    v:动词
    m:情态动词
    s:代词主语
    o:代词宾语
    t:The
    以空格分割
    */
    point_t points[WORDS_SIZE] = {
        (point_t){4, "t n v o"}, // The + n. + v. + 代词宾语
        (point_t){4, "s m v o"}, // 代词主语 + model v. + v. + 代词宾语
        (point_t){3, "s v o"},   // 代词主语 + v. + 代词宾语
        (point_t){2, "v o"}      // v. + 代词宾语
    }; // 语法集
    
    
    // 判断数组里是否有指定元素
    c_bool is_in_array(word arr[], word w){
        int i;
        // 循环遍历数组
        for(i=0; i<WORDS_SIZE; i++){
            if(strcmp(arr[i], w) == 0) // strcmp(3)比较字符串,相等返回0
                return True;
        }
        return False;
    }
    
    // 生成随机数
    int get_random(int max){
        int result = rand();
        result %= max; // 将随机数取余,即可得到0-max的随机值
        return result;
    }
    
    // 从数组里随机取出成员
    char *get_random_array(word arr[]){
        // 返回arr随机下标的内容
        return arr[get_random(WORDS_SIZE - 1)];
    }
    
    // 获取一个词的词性
    word_type_t get_words_type(word w){
        // 判断是否在指定数组
        if(is_in_array(n, w))return N;
        if(is_in_array(v, w))return V;
        if(is_in_array(model_v, w))return MV;
        if(is_in_array(pron_sub, w))return PS;
        if(is_in_array(pron_obj, w))return PO;
        // 判断是否为"the"
        if(strcmp(w, "the") == 0)return T;
    }
    
    // 将以字符形式存储的词性转换为word_type_t
    word_type_t char2word_type(char t){
        switch(t){
            case 'n':return N;
            case 'v':return V;
            case 'm':return MV;
            case 's':return PS;
            case 'o':return PO;
            default: return T;
        }
        return T;
    }
    
    // 随机生成指定词性的词
    char __the[4] = "the";
    char *get_random_type(word_type_t type){
        switch(type){
                    case N:return get_random_array(n);
                    case V:return get_random_array(v);
                    case MV:return get_random_array(model_v);
                    case PS:return get_random_array(pron_sub);
                    case PO:return get_random_array(pron_obj);
            case T:return __the;
                    default: return (char *)NULL;
            }
    }
    
    
    

    文件三:main.c

    
    ```c
    /*main.c*/
    /*
    程序编译方法:
    将words.h,words.c,main.c放在一个目录下
    终端输入gcc words.c main.c即可编译成功
    输入./a.out即可运行,Windows输入./a.exe
    程序功能:
    输入0-2个词,并随机产生两个词,按照
    输入的词 + 随机词 + 随机词 + 输入的词组成一句通顺的话(不保证完全通顺)
    */
    #include "words.h"
    
    int main(void){
        srand((unsigned int)time(NULL));
        // 定义首词和尾词
        word first;
        word last;
        // 获取字符串
        printf("Input first word. Input 'n' if it would be null\n");
        scanf("%s", first);
        printf("Input last word. Input 'n' if it would be null\n");
        scanf("%s", last);
        int count = 4; // 计数
        // 定义判断输入是否为空的代码
        #define FIRST ((first[0] == 'n') && (first[1] == '\0'))
        #define LAST ((last[0] == 'n') && (last[1] == '\0'))
        // 没有首词
        if(FIRST)count--;
        // 没有尾词
        if(LAST)count--;
        // 获取词性
        word_type_t first_type;
        word_type_t last_type;
        if(!FIRST)
            first_type = get_words_type(first);
        if(!LAST)
            last_type = get_words_type(last);
        // 遍历语法集
        int i;
        c_bool find = False; // 是否找到合适的
        word wr[count];      // 生成的词的数组
        for(i=0; i<WORDS_SIZE; i++){
            // 如果词的数量和已有词的数量一致
            if(points[i].size == count){
                // 选用
                // 获取具体语法信息
                char tmp[count];
                int k;
                for(k=0; k<count; k++){
                    // 将字符串语法信息转换为字符语法信息数组
                    tmp[k] = points[i].point[k*2];
                }
                // 建立word_type_t语法信息数组
                word_type_t tp[count];
                // 转换语法信息数组
                for(k=0; k<count; k++){
                    tp[k] = char2word_type(tmp[k]);
                }
                // 如果首词和尾词都为空
                if(FIRST && LAST){
                    find = True;
                    for(k=0; k<count; k++)
                        strcpy(wr[k], get_random_type(tp[k]));
                }else if(FIRST && last_type == tp[count-1]){ // 如果首词为空且语法正确
                    find = True;
                    for(k=0; k<count - 1; k++)
                        strcpy(wr[k], get_random_type(tp[k]));
                    strcpy(wr[count - 1], last);
                }else if(LAST && first_type == tp[0]){ // 如果尾词为空且语法正确
                    find = True;
                    strcpy(wr[0], first);
                    for(k=1; k<count; k++)
                        strcpy(wr[k], get_random_type(tp[k]));
                }
                // 如果都不为空且语法正确
                else if((first_type == tp[0]) && (last_type == tp[count-1])){
                    // 一致,就可以随机生成了
                    find = True; // 设置已找到
                    strcpy(wr[0], first);
                    for(k=1; k<count - 1; k++)
                        strcpy(wr[k], get_random_type(tp[k]));
                    strcpy(wr[count - 1], last);
                }
                // 语法错误,就进行下一轮循环
            }
        }
        // 如果没有找到合适的
        if(!find)printf("cannot create...\n");
        else{ // 找到了
            // 输出字符串
            for(i=0; i<count; i++){
                printf("%s ", wr[i]);
            }
            printf("\n");
        }
        return 0;
    }
    
    
    

    我尽量地多注释,但是难免有问题。如有问题,欢迎随时评论或私聊
    望采纳

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 8月12日
  • 已采纳回答 8月4日
  • 修改了问题 7月28日
  • 修改了问题 7月28日
  • 展开全部

悬赏问题

  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了