Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use single letters to form words

Tags:

c++

Hey I currently have this code. It gets the user to input strings into an array, with a limit of 5. I plan to use the array to then form words from the array. How can I achieve this?

    const int row = 5;
    char array[row];
    char count = 0;
    char letter;
    while (count < 5)
    {
        cout << "Enter a letter: ";
        cin >> letter;
        array[count] = letter;
        count++;
    }
    cout << "Letter inputed" << endl;
    for (count = 0; count < 5; count++)
    {
        cout << array[count] << " " <<  endl;
    }
    system("pause");
like image 707
user2881555 Avatar asked Oct 24 '13 15:10

user2881555


People also ask

What words can I make with the letters Single?

sealing, leasing, linages, singled, dingles, engilds, seeling, selfing, niggles, sniggle, leggins, shingle, english, jingles, selling, mingles, lensing, eloigns, lingoes, longies, legions, lingers, slinger, singles, sniglet, glisten, singlet, tingles, slewing, swingle.

What is a single letter word called?

One-Letter Words. a, I. Most Frequent Two-Letter Words. of, to, in, it, is, be, as, at, so, we, he, by, or, on, do, if, me, my, up, an, go, no, us, am. Most Frequent Three-Letter Words.

Is single letter counted as a word?

Strictly speaking, every letter is a word. "M" is the name of the letter "m" and is a noun. 3. But if you are asking whether the letters are words when they are used to make up longer words then no.

How many single letter words are there in the English language?

So we might instead simply note that, of the 26 possible single-letter "words," only three of them have meanings that go beyond tautological references to the letters themselves, or to representations thereof ("I drove my T-top to the Y intersection..."), and decide for ourselves how significant that difference is.


3 Answers

Here's a hint to get you started on the right track: don't even consider using std::next_permutation unless this is something you'll only ever use once or twice (and probably not even then, because it's actually more complicated than doing the job right).

Using std::next_permutation, your function will be approximately N! times slower than necessary1 -- in the case of 5 letters, that'll be 120 times slower, and if you ever use longer words, it'll get worse very quickly (e.g., for 10 letters it's over 3.5 million).

Instead, start by pre-processing your dictionary. Instead of a std::set<std::string> of words, create an std::map<std::string, std::vector<string>> (or std::unordered_map, though English has few enough words that this probably won't make a huge difference). As you read in a word from the dictionary, create a sorted version of that string. Use that as the key, and push the original version of the word onto the vector for that key.

Then when you get a word from the user, sort it, look that up in the map, and the associated vector will contain every word (from your dictionary) that can be created from those letters.


1. If you use std::map instead of std::unordered_map, that should be something like N!/(log N), but N! grows so fast and log N grows so slowly that it the difference is negligible (if you get N large enough that log N = 3, N! will be so large that N!/log N computation steps...well, you start to get into questions of cosmology, like whether the universe will have died of heat death before then (to which the answer seems to be "yes, probably").

like image 81
Jerry Coffin Avatar answered Oct 07 '22 16:10

Jerry Coffin


Here's a hint to get you started. There's a function in the standard library called std::next_permutation. Assuming you have a dictionary of words to check against, a possible solution could look like this:

std::sort(array, array + row);
do {
    // Check if array is a word.
} while (std::next_permutation(array, array + row));

This will cycle through every permutation of letters. It's now up to you to verify that it is a valid word.

like image 25
bstamour Avatar answered Oct 07 '22 16:10

bstamour


This solution uses an associative array to map from sorted letters of the word to the words having such sorted letters. It's thus possible to get an answer with one lookup in the map, which takes asymptotically O(log N) time, where N is a size of your dictionary.

Create a file named dic.txt. In case you're using Visual Studio it should be in the same directory as your *.cpp files. Put several words inside in a "word in a row" format. Try the following code:

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;

int main() {
    // Dictionary file is in a "word in a row" format
    map< string, vector<string> > dictionary;
    ifstream dictionary_file("dic.txt");
    if (!dictionary_file.good()) {
        cout << "File doesn't exist" << endl;
        return 0;
    }
    string word;
    while (dictionary_file >> word) {
        string key = word;
        sort(key.begin(), key.end());
        dictionary[key].push_back(word);
    }

    // Read the letters
    string letters;
    cin >> letters;
    if (letters.size() > 5) {
        cout << "Too much letters" << endl;
        return 0;
    }

    // Sort the letters
    sort(letters.begin(), letters.end());

    // Output the answers
    vector<string> & ret = dictionary[letters];
    for (size_t i = 0, ilen = ret.size(); i < ilen; ++i) {
        cout << ret[i] << endl;
    }
}

Mention that such a solution cares for a case your letters are in. In case you don't need it, you can add calls to strtolower function (got that name from PHP) before you add a word to your dictionary and before you sort your letters.

string strtolowers(string const & word) {
    string ret = word;
    transform(ret.begin(), ret.end(), ret.begin(), tolower);
    return ret;
}

You'll need to add <cctype> header for this function to work.

like image 40
polkovnikov.ph Avatar answered Oct 07 '22 15:10

polkovnikov.ph