Словари и работа с ними

Konstantin
Konstantin Ostrovsky
2019-05-08 08:11:19
8

 

Что такое словарь?

Слова́рь — книга или любой другой источник, информация в котором упорядочена c помощью разбивки на небольшие статьи, отсортированные по названию или тематике. Различают энциклопедические и лингвистические словари.

С развитием компьютерной техники всё большее распространение получают электронные словари и онлайн-словари.

Источник https://ru.wikipedia.org

 

Нас, конечно же, интересуют электронные словари и все что с ними связано. Электронный словарь представляет собой упорядоченную структуру данных, в которой при помощи программных средств можно быстро и просто найти необходимую информацию(слово). 

 

Зачем нужны электронные словари?

Словари часто используют для проверки валидности текста, к примеру в программах из пакета Microsoft Office. Если слово было написано с ошибкой, то оно будет подчеркнуто красным цветом. 

Представьте как было бы круто добавить такую валидацию в Ваш мессенджер или игровой чат. Словари можно использовать в играх-генераторах, к примеру в игре Scrabble определенно стоит использовать такой словарь. 

Вы даже можете использовать словари для тренировки искусственных нейронных сетей. К примеру создать ИНС, которая будет генерировать Lorem Ipsum.

Большинство словарей содержит полную информацию о слове, такую как падеж, морфологический разбор слова, часть речи и прочее. Но стоит понимать, что размер словаря будет напрямую зависеть от количества информации.

 

Где взять?

Вариантов множество. Но нужно быть готовым к тому, что словарь будет доступен не в том виде, в котором Вы сможете его использовать.

Мой выбор пал на использование SQLite для работы с словарем. Для конвертации был написан небольшой скрипт на NodeJS. Он работает достаточно примитивно, просто загоняет в базу записи из массива, который он строит на основе словаря из файла *txt. Я думаю, что Вам будет не трудно модифицировать скрипт для работы с CSV, XML и другими форматами данных. Время работы с 65 000 записей ~ 5секунд. Все записи добавляются одной транзакцией. Честно говоря, я не проверял какую нагрузку сможет выдержать скрипт, поэтому в случае необходимости, Вы можете модифицировать его и разбить на несколько транзаций. Скачать скрипт+словарь можно по этой ссылке.

Если база будет в формате sql, то Вы с легкостью можете перегнать ее в SQLite3 при помощи простой команды:

sqlite3 database.sqlite3 < db.sql

Несколько источников с бесплатными словарями русского языка:

  1. http://www.speakrus.ru/dict/
  2. https://shra.ru/2017/03/baza-dannykh-russkikh-slov-sushhestvitelnye/
  3. https://github.com/danakt/russian-words
  4. http://ivanov-portal.ru/slovari/slovari.html
  5. http://blog.harrix.org/article/3334

 

Как использовать SQLite в Unity?

Существует много реализаций библиотек и готовых решений, которые Вы можете найти на https://assetstore.unity.com.

В своем последнем проекте я использовал https://github.com/rizasif/sqlite-unity-plugin.

Плагин *.dll поддерживает компиляцию под х64, которую с недавних пор так любит Google Play.  

В заключение, хочу продемонстрировать небольшой класс для работы с словарем SQLite в Unity. Предполагается что словарь будет загружен при первом входе в игру.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Data;
using Mono.Data.Sqlite;
using System.IO;
using UnityEngine.Networking;

public class DB : MonoBehaviour
{ 
    [HideInInspector]
    public IDbConnection dbcon;
    
    [HideInInspector]
    public static string wordsTable = "words";

    public static bool connected = false;
    private string DBFilename = "db.sqlite";

    void Start()
    {
      Connect();
    }

    // Подключение к базе данных
    void Connect() {

      if (System.IO.File.Exists(Application.persistentDataPath + "/" + DBFilename))
      {
        string connection = "URI=file:" + Application.persistentDataPath + "/" + DBFilename;
        dbcon = new SqliteConnection(connection);
        dbcon.Open();
        Debug.Log("DB exists");
        connected = true;

      }else{
        StartCoroutine(DownloadDB(DBFilename));
      }

    }

    // Загружаем базу данных из внешнего источника
    IEnumerator DownloadDB(string file_name)
    {
        Debug.Log("Download database...");
        string url = "https://example.com/" + file_name;
        using (UnityWebRequest www = UnityWebRequest.Get(url))
        {
            yield return www.SendWebRequest();
            if (www.isNetworkError || www.isHttpError)
            {
                Debug.Log(www.error);
            }
            else
            {
                string savePath = string.Format("{0}/{1}", Application.persistentDataPath, file_name);
                System.IO.File.WriteAllBytes(savePath, www.downloadHandler.data);
                Connect();
            }
        }
    }

    // Получаем все таблицы и ищем в них нужную. Если нет - создаем
    bool CheckExistsTable(string table) {
      var tables = GetTable(table);
      var exists = false;
      while(tables.Read()) if(tables[0].ToString() == table) exists = true;
      if(exists == false) CreateTables(table);

      return exists;
    }

    // Создать таблицу, если она не создана
    void CreateTables(string table) {
      var dbcmd = dbcon.CreateCommand();
      string q_createTable =
        "CREATE TABLE IF NOT EXISTS " + table + " (" +
        "id" + " INTEGER PRIMARY KEY, " +
        "val" + " STRING )";

      dbcmd.CommandText = q_createTable;
      dbcmd.ExecuteReader();
    }

    // Добавить запись
    void InstertWord(string word, string table) {
      var dbcmd2 = dbcon.CreateCommand();
      dbcmd2.CommandText = "INSERT INTO "+table+" (val) VALUES ('"+word+"')";
      dbcmd2.ExecuteNonQuery();
    }

    // Получить все записи
    IDataReader GetRows(string table) {
      var dbcmd3 = dbcon.CreateCommand();
      string query ="SELECT * FROM "+table;
      dbcmd3.CommandText = query;
      var reader = dbcmd3.ExecuteReader();

      return reader;
    }

    // Найти запись в базе
    public IDataReader Find(string name, string table) {
      var dbcmd3 = dbcon.CreateCommand();
      string query ="SELECT * FROM "+table+" WHERE val='"+name+"'";
      dbcmd3.CommandText = query;
      var reader = dbcmd3.ExecuteReader();

      return reader;
    }

    // Получить таблицу из базы
    IDataReader GetTable(string name) {
      var dbcmd3 = dbcon.CreateCommand();
      string query ="SELECT name FROM sqlite_master WHERE type='table' AND name='"+name+"';";
      dbcmd3.CommandText = query;
      var reader = dbcmd3.ExecuteReader();

      return reader;
    }

    // Закрыть соединение
    void Close() {
      dbcon.Close();
      connected = false
    }

}