Compare commits

..

No commits in common. "744d0f7a3a121c98bc9325fc09db0e761cb890e8" and "e4e27d421a0ec8fb86c2e0e88d7538a1900cf99f" have entirely different histories.

10 changed files with 53 additions and 229 deletions

3
.gitignore vendored
View file

@ -2,6 +2,3 @@
*.d *.d
*a.out* *a.out*
build build
.cache/
words.txt
compile_commands.json

View file

@ -1,2 +0,0 @@
format:
find . -regex '.*\.\(c\|cpp\|cc\|cxx\|h\|hpp\|hh\|hxx\)' -exec clang-format {} +

View file

@ -1,24 +0,0 @@
CXX = g++
CXXFLAGS = -g3 -Werror -Wall -Wpedantic -Wunused-variable -std=c++17
SRC = $(wildcard *.cc)
OBJ = $(SRC:.cc=.o)
all: spell edit $(OBJ)
edit: test_edit_distance.o edit_distance.o
@echo "Building & linking $@"
@$(CXX) $(CXXFLAGS) $^ -o $@
spell: spell.o word.o dictionary.o
@echo "Building & linking $@"
@$(CXX) $(CXXFLAGS) $^ -o $@
%.o:%.cc
@echo "Building $@"
@$(CXX) -c $(CXXFLAGS) $< -o $@
clean:
rm -f *.o spell edit
.PHONY: clean

View file

@ -1,82 +1,22 @@
#include "dictionary.h"
#include "word.h"
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <fstream>
#include <iostream>
#include <algorithm>
#include "word.h"
#include "dictionary.h"
using std::string; using std::string;
using std::vector; using std::vector;
// using std::filesystem::path;
Dictionary::Dictionary() {} Dictionary::Dictionary() {
bool Dictionary::contains(const string &word) const { return true; }
vector<string> Dictionary::get_suggestions(const string &word) const {
vector<string> suggestions;
// add_trigram_suggestions(suggestions, word);
// rank_suggestions(suggestions, word);
// trim_suggestions(suggestions);
return suggestions;
} }
// Function to generate trigrams from a string bool Dictionary::contains(const string& word) const {
std::vector<std::string> get_trigrams(const std::string &text) { return true;
std::vector<std::string> trigrams;
if (text.size() < 3) {
return trigrams; // Return an empty vector if the input is too short
}
for (size_t i = 0; i <= text.size() - 3; ++i) {
trigrams.push_back(
text.substr(i, 3)); // Extract a substring of length 3
}
return trigrams;
} }
int Dictionary::spit(path p) { vector<string> Dictionary::get_suggestions(const string& word) const {
std::ofstream file(p); vector<string> suggestions;
return suggestions;
if (!file.is_open()) {
std::cerr << "Error opening file! " << std::endl;
return 1;
}
for (int a = 0; a < 25; a++) {
for (auto &word : words[a]) {
std::vector<std::string> trias = get_trigrams(word.get_word());
file << word << " " << trias.size();
for (auto tria : trias) {
file << " " << tria;
}
file << std::endl;
}
}
file.flush();
file.close();
return 0;
}
int Dictionary::slurp(path p) {
std::ifstream file(p.string());
if (!file.is_open()) {
std::cerr << "Error opening file! " << std::endl;
return 1;
}
std::string line;
while (std::getline(file, line)) {
words[line.size()].push_back(Word(line, get_trigrams(line)));
}
file.close();
return 0;
} }

View file

@ -1,24 +1,15 @@
#ifndef DICTIONARY_H #ifndef DICTIONARY_H
#define DICTIONARY_H #define DICTIONARY_H
#include "word.h"
#include <filesystem>
#include <string> #include <string>
#include <vector> #include <vector>
using std::vector;
using std::filesystem::path;
class Dictionary { class Dictionary {
public: public:
Dictionary(); Dictionary();
bool contains(const std::string &word) const; bool contains(const std::string& word) const;
std::vector<std::string> get_suggestions(const std::string &word) const; std::vector<std::string> get_suggestions(const std::string& word) const;
int slurp(path p); private:
int spit(path p);
private:
vector<Word> words[25];
}; };
#endif #endif

View file

@ -1,35 +0,0 @@
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int edit_distance(const std::string& s1, const std::string& s2) {
size_t m = s1.size();
size_t n = s2.size();
// Create a 2D DP table
std::vector<std::vector<int>> dp(m + 1, std::vector<int>(n + 1));
// Fill the base cases
for (size_t i = 0; i <= m; ++i)
dp[i][0] = i; // Deletion cost
for (size_t j = 0; j <= n; ++j)
dp[0][j] = j; // Insertion cost
// Fill the DP table
for (size_t i = 1; i <= m; ++i) {
for (size_t j = 1; j <= n; ++j) {
if (s1[i - 1] == s2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1]; // No operation needed
} else {
dp[i][j] = 1 + std::min({dp[i - 1][j], // Deletion
dp[i][j - 1], // Insertion
dp[i - 1][j - 1] // Substitution
});
}
}
}
return dp[m][n];
}

View file

@ -1,18 +0,0 @@
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
/**
* @brief Computes the edit distance (Levenshtein distance) between two strings.
*
* The edit distance is defined as the minimum number of single-character edits
* (insertions, deletions, or substitutions) required to transform one string into the other.
*
* This implementation uses dynamic programming to compute the distance efficiently.
*
* @param s1 The first string.
* @param s2 The second string.
* @return The edit distance between the two strings.
*/
int edit_distance(const std::string& s1, const std::string& s2);

View file

@ -1,17 +1,18 @@
#include "dictionary.h"
#include <cctype>
#include <filesystem>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <algorithm>
#include <vector> #include <vector>
#include <cctype>
#include "dictionary.h"
using std::string;
using std::vector;
using std::cin; using std::cin;
using std::cout; using std::cout;
using std::endl; using std::endl;
using std::string;
using std::vector;
void check_word(const string &word, const Dictionary &dict) { void check_word(const string& word, const Dictionary& dict)
{
if (dict.contains(word)) { if (dict.contains(word)) {
cout << "Correct." << endl; cout << "Correct." << endl;
} else { } else {
@ -20,22 +21,18 @@ void check_word(const string &word, const Dictionary &dict) {
cout << "Wrong, no suggestions." << endl; cout << "Wrong, no suggestions." << endl;
} else { } else {
cout << "Wrong. Suggestions:" << endl; cout << "Wrong. Suggestions:" << endl;
for (const auto &w : suggestions) { for (const auto& w : suggestions) {
cout << " " << w << endl; cout << " " << w << endl;
} }
} }
} }
} }
int main() { int main() {
Dictionary dict; Dictionary dict;
string word; string word;
dict.slurp(std::filesystem::path("/usr/share/dict/words")); while (cin >> word) {
// dict.spit(std::filesystem::path("words.txt")); transform(word.begin(), word.end(), word.begin(), ::tolower);
check_word(word, dict);
// while (cin >> word) { }
// transform(word.begin(), word.end(), word.begin(), ::tolower);
// check_word(word, dict);
// }
return 0; return 0;
} }

View file

@ -1,34 +1,16 @@
#include "word.h"
#include <algorithm>
#include <string> #include <string>
#include <vector> #include <vector>
#include "word.h"
using std::string;
using std::vector; using std::vector;
using std::string;
Word::Word(const string &w, const vector<string> &t) : word(w), triagrams(t) { Word::Word(const string& w, const vector<string>& t) {}
std::sort(triagrams.begin(), triagrams.end());
string Word::get_word() const {
return string();
} }
string Word::get_word() const { return string(); } unsigned int Word::get_matches(const vector<string>& t) const {
return 0;
unsigned int Word::get_matches(const vector<string> &t) const {
unsigned int matches = 0;
for (const auto &triagram : t) {
if (std::binary_search(triagrams.begin(), triagrams.end(), triagram)) {
++matches;
}
}
return matches;
}
std::ostream &operator<<(std::ostream &out, const Word &w) {
auto space = string(" ");
out << w.word;
out << space;
for (const auto &tria : w.triagrams) {
out << space << tria;
}
return out;
} }

View file

@ -1,25 +1,21 @@
#pragma once #ifndef WORD_H
#define WORD_H
#include <string> #include <string>
#include <vector> #include <vector>
/*
* Contains a word and its triagrams
*/
class Word { class Word {
public: public:
/** Creates a word w with the sorted trigrams t */ /* Creates a word w with the sorted trigrams t */
Word(const std::string &w, const std::vector<std::string> &t); Word(const std::string& w, const std::vector<std::string>& t);
/** Returns the word */ /* Returns the word */
std::string get_word() const; std::string get_word() const;
/** Returns how many of the trigrams in t that are present /* Returns how many of the trigrams in t that are present
in this word's trigram vector */ in this word's trigram vector */
unsigned int get_matches(const std::vector<std::string> &t) const; unsigned int get_matches(const std::vector<std::string>& t) const;
private:
private:
const std::string word;
const std::vector<std::string> triagrams;
friend std::ostream &operator<<(std::ostream &out, const Word &o);
}; };
#endif