从数据库中查找单词

devtools/2024/9/20 3:33:15/ 标签: 数据库, oracle

我们知道,从文件中查找是一行一行的查找匹配,但是数据库就可以快速查找,节约时间;

我们先来讲一下大概思路(所有都为C语言);

首先使用access函数判断数据库字典有没有被创建,如果创建了就跳过创建这个步骤,要不然每次加载都会耗费很多时间(几乎1-2分钟)(等待的过程蛮漫长的);

这是使用到的头文件;

#include <sqlite3.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
/*********************定义的全局变量函数***************/
sqlite3 *pdb;
char temp[4096] = {0};
char *errmsg = NULL;

这是主函数的逻辑;

int main(void)
{int ret = 0;int ok = 0;ok = access("/home/linux/Desktop/2024/20240822/dict.db",F_OK); //这个路径是我自己的,可以替换if(0 == ok)  //access函数的特性,F_OK是用于查看该文件是否存在,成功返回0{ret = Open();  //打开数据库if(ret == -1)  //错误处理{fprintf(stderr,"fail to sqlite_open:%s\n",sqlite3_errmsg(pdb));return -1;}ret = word_put();  //传入想要查询的单词if(ret == -1)        //错误处理{fprintf(stderr,"fail to sqlite_exec:%s\n",errmsg);sqlite3_free(errmsg);   //释放掉错误码的空间sqlite3_close(pdb);    //关闭数据库return -1;}return 0;}if(-1 == ok){printf("不存在,开始创建\n");ret = Open();if(ret == -1){fprintf(stderr,"fail to sqlite_open:%s\n",sqlite3_errmsg(pdb));return -1;}ret = word_creat();if(ret == -1){return -1;}ret = word_put();if(ret == -1){fprintf(stderr,"fail to sqlite_exec:%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(pdb);return -1;}}sqlite3_close(pdb);return 0;
}

打开数据库的函数;

/****************************************************/
int Open(void)
{int ret = 0;ret = sqlite3_open("dict.db",&pdb);if(ret != SQLITE_OK){return -1;}return 0;
}
/*****************************************************/

创建dict 数据库,并将字典加载到数据库中;

/*************************************************/
int word_creat()
{int ret = 0;FILE *fp = NULL;;char *nsize = NULL;char *pword = NULL;char *pmean = NULL;char tempword[1024] = {0};sprintf(temp,"create table dict(id integer primary key asc, word text, mean text)");ret = sqlite3_exec(pdb,temp,NULL,NULL,&errmsg); //使用sqlite3_exec函数执行语句if(ret != SQLITE_OK)  //错误处理{fprintf(stderr,"fail to sqlite_exec:%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(pdb);return -1;}fp = fopen("dict.txt","r");  //打开字典文件if(NULL == fp){perror("fail to fopen dict.txt");sqlite3_close(pdb);return -1;}while(1){memset(temp,0,sizeof(temp));   //对temp清零nsize = fgets(temp,sizeof(temp),fp);  //读取一行字符串temp[strlen(temp)-1] = '\0';if(nsize == NULL){break;}pword = strtok(temp," ");   //进行分割pmean = strtok(NULL,"\r\n");sprintf(tempword,"insert into dict values (NULL,\"%s\",\"%s\")",pword,pmean);ret = sqlite3_exec(pdb,tempword,NULL,NULL,&errmsg);  //插入单词和含义if(ret != SQLITE_OK){fprintf(stderr,"fail to sqlite_exec11:%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(pdb);return -1;}}fclose(fp);  return 0;
}
/*****************************************************/

查询单词;

/*****************************************************/
int word_put(void)
{int ret = 0;char input[1024] = {0};printf("录入完成!\n");memset(temp,0,sizeof(temp));fgets(temp,sizeof(temp),stdin);temp[strlen(temp)-1] = '\0';sprintf(input,"select word ,mean from dict where word = \"%s\"",temp);ret = sqlite3_exec(pdb,input,callback,NULL,&errmsg);if(ret != SQLITE_OK){return -1;}return 0;
}
/*************************************************/

回调函数;

/**************************************************/
int callback(void * arg, int column, char **pcontet, char **ptitle)
{printf("%s : %s\n",pcontet[0],pcontet[1]);  //打印查到的单词和意思return 0;
}
/****************************************************/

这里面有几个有意思的点:

1.字符串的分割;

        因为原字典里的单词长这样:a                indef art one \r\n,

        用strtok分割,第一次分割空格之前的单词,第二次分割到\r\n;

2.在加载过程中显示加载进度;

        由于加载过程中太无聊,想要一点动态显示加载进度可以这样做,

//加载单词文件时,fseek将光标偏移到最末尾      

    fseek(fp, 0, SEEK_END);

//ftell获得光表的偏移量

    tlen = ftell(fp);

//再将光标定义回开头

    rewind(fp);

这样就获得了整个文件的大小;

//读取一行信息

        pret = fgets(tmpbuff, sizeof(tmpbuff), fp);

//获得这一行的大小

        clen = ftell(fp);

//转换成double型打印

        printf("已加载: %.2lf\r", (double)clen / (double)tlen * 100);

//刷新

        fflush(fp);

加上循环,这样就可以动态显示加载进度了;

3.显示加载用时;

想要显示整个文件加载到数据库需要多长时间可以这样做;

在加载文件之前使用gettimeofday; gettimeofday(&start, NULL);在加载文件完成后使用;gettimeofday(&end, NULL);打印;
printf("加载数据库文件成功! 耗时: %.2lf s  CPU耗时:%.2lf s\n", ((double)(end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)) / 1000000,((double)(cpuend - cpustart)) / CLOCKS_PER_SEC);

4.使用makefile

因为这个程序调用了sqlite3库,所以在编译时需要加上 -lsqlite3,要是每次都加可能比较麻烦,所以我们创建makefile文件;

.PHONY:是一个伪指令,

a.out:select_world.cgcc $^ -o $@ -lsqlite3
.PHONY:
clean:rm a.out

5.如何将加载时间压缩到极致;

第一种方法:关闭磁盘写同步

        PRAGMA synchronous = NORMAL;

第二种方法:开启事务

        begin 和 commit;

第三种办法:使用预处理SQL语句机制实现提升数据库效率

今天就到这里啦!


http://www.ppmy.cn/devtools/101936.html

相关文章

【JavaEE初阶】TCP协议

目录 &#x1f332;TCP协议的概念 &#x1f6a9;TCP协议段格式 &#x1f6a9;TCP的特性 &#x1f333;TCP原理 &#x1f6a9;确认应答机制(安全机制) &#x1f6a9;超时重传(安全机制) &#x1f6a9; 连接管理(安全机制) &#x1f6a9;滑动窗口(效率机制) &#x1f6a…

通过IDEA创建spring boot的web项目

1.Fle->New->Project,选择Maven&#xff0c;点击Next 2.修改项目名称&#xff0c;点击Finish 3.项目创建完毕&#xff0c;等待Maven下载完成 4.修改pom.xml文件&#xff0c;改成如下内容 <?xml version"1.0" encoding"UTF-8"?> <pr…

Python知识点:如何使用MySQL与PyMySQL进行数据库操作

使用MySQL与PyMySQL进行数据库操作的过程与使用PostgreSQL与Psycopg2类似。以下是一个简单的指南&#xff0c;介绍如何使用PyMySQL连接到MySQL数据库并进行基本的数据库操作。 1. 安装PyMySQL 首先&#xff0c;你需要安装PyMySQL库。如果还未安装&#xff0c;可以使用以下命令…

配置策略路由实战 附带基础网络知识

背景 作为一个软件开发人员&#xff0c;不可能做到只负责业务开发工作&#xff0c;一旦功能上线或者系统切换就会遇到非常多考验开发人员个人能力的场景&#xff0c;网络调整就是非常重要的一个方面&#xff0c;如果你在系统上线的过程中无法处理一些简单的网络问题或者听不懂…

PHP农场扶农系统智慧认养智慧乡村系统农场系统小程序源码

&#x1f331;科技赋能田园梦 —— 探索“农场扶农系统”与“智慧认养智慧乡村”新篇章&#x1f680; &#x1f308;【开篇&#xff1a;田园新风尚&#xff0c;科技引领未来】 在快节奏的都市生活中&#xff0c;你是否曾梦想过拥有一片属于自己的绿色天地&#xff1f;现在&am…

推荐系统实战第六章-粗排和重排(上)粗排

粗排是介于召回和精排之间的&#xff0c;由于多路召回筛选得到物料库量级仍然很大&#xff0c;无法满足在线实时训练的要求。并且如果召回后直接精排&#xff0c;可能对推荐系统精度无法保证。 一、模型结构 &#xff08;一&#xff09;粗排双塔和召回双塔的异同 1、相同点 …

一文搞懂大模型!基础知识、 LLM 应用、 RAG 、 Agent 与未来发展

LLM 探秘&#xff1a;想要深入了解人工智能界的“新宠”大型语言模型&#xff08;LLM&#xff09;吗&#xff1f;本文将带你走进 LLM 的世界&#xff0c;从入门知识到实际应用&#xff0c;全方位解读这个充满魔力的“大模型”。我们将一起揭开 LLM 的神秘面纱&#xff0c;领略其…

最佳实践 | SaleSmartly用HelpLook搭建知识库,客服效率提升,服务好全球数万客户

SaleSmartly&#xff0c;作为全渠道私域沟通工具的佼佼者&#xff0c;使用HelpLook开启了全新智能客服服务新体验。通过使用HelpLook搭建了AI知识库和博客中心&#xff0c;SaleSmartly不仅大幅提升了客服效率&#xff0c;还成功优化了品牌形象&#xff0c;服务覆盖全球数万客户…

VCTP(Visual Chain-of-Thought Prompting for Knowledge-Based Visual Reasoning)论文

目录 摘要介绍相关工作方法总体模型细节 实验 摘要 知识型视觉推理仍然是一个艰巨的任务&#xff0c;因为它不仅要求机器从视觉场景中解释概念和关系&#xff0c;而且还需要将它们与外部世界知识联系起来&#xff0c;对开放世界问题进行推理链。然而&#xff0c;以前的工作将视…

Kubernetes(k8s)中部署WordPress

在Kubernetes&#xff08;k8s&#xff09;中部署WordPress通常涉及创建一个Deployment来管理WordPress的Pod&#xff0c;以及一个Service来暴露WordPress应用。此外&#xff0c;由于WordPress需要数据库支持&#xff0c;你还需要部署一个MySQL或MariaDB的Pod和Service。 以下是…

redis分布式是如何实现的(面试版)

需要结合项目中的业务进行回答&#xff0c;通常情况下&#xff0c;分布式锁使用的场景&#xff1a;集群情况下的定时任务、抢单、幂等性场景。 下面先来看一个抢卷场景&#xff1a; 以下情况会出现超卖情况&#xff1a; 因为线程会交替执行&#xff0c;所以线程查询优惠价的数…

探索Git:分布式版本控制系统的力量(二)

&#x1f600;前言 本篇博文是关于分布式版本控制系统Git的一些基本介绍&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我…

Android自定义一个带背景的圆环形进度条(Kotlin)

前言 在Android开发过程中&#xff0c;难免遇到一些复杂的UI组件需要我们自定义 当然使用系统原生组件拼凑也能完成&#xff0c;但是UI复杂度增加了不说&#xff0c;在更新UI状态的时候还不好管理&#xff0c;最重要的是复用的价值不大&#xff0c;上述的操作很容易引增加码冗…

Oracle字符串聚合函数LISTAGG

在Oracle 19c中&#xff0c;LISTAGG函数是一个非常有用的字符串聚合函数&#xff0c;它可以将来自多个行的值连接成一个单独的字符串。这个函数特别适用于将分组内的多个值合并为一个逗号分隔&#xff08;或其他分隔符&#xff09;的字符串。 LISTAGG函数的基本语法如下&#…

LeetCode 3133.数组最后一个元素的最小值:位运算+双指针

【LetMeFly】3133.数组最后一个元素的最小值&#xff1a;位运算双指针 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-array-end/ 给你两个整数 n 和 x 。你需要构造一个长度为 n 的 正整数 数组 nums &#xff0c;对于所有 0 < i < n - 1 &#xff0…

网络游戏运营

游戏运营是将一款游戏平台推入市场&#xff0c;并通过一系列的策略和行动&#xff0c;使玩家从接触、认识到最终成为忠实玩家的过程。这一过程涵盖了多个方面&#xff0c;包括前期准备、上线运营、活动策划、数据分析、渠道合作以及用户维护等。以下是对游戏运营的详细解析&…

用ChatGPT精确营销:如何让AI深度理解并推广你的产品

在现代商业中,人工智能(AI)正迅速成为企业成功的关键因素之一。ChatGPT作为一种强大的语言模型,不仅能回答问题,还能通过深度理解和互动,帮助企业精准推广产品。然而,如何让ChatGPT真正了解并有效地推广你的产品,是许多使用者面临的挑战。在本文中,我们将探讨如何通过…

debian/ubuntu 通过串口连接WiFi

修改 /etc/wpa_supplicant.conf&#xff0c;如果没有这个文件就创建文件 vi /etc/wpa_supplicant.conf设置wifi信息 network{ssid"这里是你的wifi账号"psk"这里是你的wifi密码" }连接wifi killall wpa_supplicant wpa_supplicant -i wlan0 -c /etc/wpa_…

SQLite 插入数据并返回自增ID

要插入数据并返回自增ID&#xff0c;我们可以使用SQLite的last_insert_rowid()函数。这个函数返回了最后一次插入操作的自增ID。 下面我们通过一个示例来演示如何插入数据并返回自增ID。 首先&#xff0c;创建一个表来存储学生信息&#xff1a; CREATE TABLE students (id I…

【研究生论文】—— 综述怎么写

怎么写综述 “综述”指的是对某一特定主题或领域h的文献、研究、进展等进行系统性回顾和总结的一种文章类型。很多时候我们需要知道的不是综述是什么&#xff0c;而是综述不是什么&#xff0c;综述不是单纯的查询报告&#xff0c;综述需要在自己的查询结果上面提出自己的看法和…