C++ coding (spelling check)

1) Create a few tweet abbreviations that can be decoded. Add support for abbreviations.

2) For abbreviations that do not match the supported abbreviations, check for common misspellings. Provide a suggestion for correct abbreviation along with the decoded meaning. For example, if the user enters "LLO", your program can output "Did you mean LOL? LOL = laughing out loud".

3) Allows the user to enter a complete tweet (140 characters or less) as a single line of text. Search the resulting string for those common abbreviations and print a list of each abbreviation along with its decoded meaning.

4) Convert the user's tweet to a decoded tweet, replacing the abbreviations directly within the tweet.

I already did number 1. Need help with 2, 3, 4

This is what I have so far:

#include <iostream>
#include <string>
using namespace std;

int main() {
string origTweet;

cout << "Enter abbreviation from tweet: " << endl;
cin >> origTweet;

if (origTweet == "LOL") {
cout << "LOL = laughing out loud" << endl;
}
else if (origTweet == "BFN") {
cout << "BFN = bye for now" << endl;
}
else if (origTweet == "FTW") {
cout << "FTW = for the win" << endl;
}
else if (origTweet == "IRL") {
cout << "IRL = in real life" << endl;
}
else if (origTweet == "ILY") {
cout << "ILY = i love you" << endl;
}
else if (origTweet == "OMG") {
cout << "OMG == oh my gosh" << endl;
}
else {
cout << "Sorry, don't know that one." << endl;
}
return 0;
}
1. I suggest using a switch statement, http://www.cprogramming.com/tutorial/lesson5.html

2. I'm not experienced enough to be able to answer this for you, but maybe someday :D

3. The syntax Getline has some interesting properties on spacing out words using " " as a signal to stop reading, Maybe you could loop this through a switch statement?

4. array[140], This might not be the best solution. But I can't really think of anything else. looping the getline from 3 will definitely help you here. And it might actually make your life easier in 3 if you use an array.
I wasn't able to figure it out but thanks
You just need to do a string search / replace I think.

http://www.cplusplus.com/reference/string/string/find/

@radar, switch selection won't work on strings
Really? I've never had any use to do that. Always assumed it worked.

Thanks for telling me, I'm sure I would have been confused in the future :D
you can also use a
std::map<std::pair<std::string original , std::string final>> registered_tweets;
I use the next_permutation to check for the spelling and compare it to map which contained the registered tweets.
http://en.cppreference.com/w/cpp/algorithm/next_permutation

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include "tweetChecker.hpp"

int main(int argc, char **argv)
{
	static_cast<void>(argc);
	static_cast<void>(argv);

	std::string tweet = "";
	TweetChecker tweeter;

	std::cout << "Enter your tweet: ";
	std::cin >> tweet;
        std::cout << "Equivalent: " << tweeter.tweet(tweet) << std::endl;

	return 0;
}


tweetChecker.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef TWEET_CHECKER_HPP
#define TWEET_CHECKER_HPP

#include <map>
#include <algorithm>

class TweetChecker
{
public:
	TweetChecker();
	TweetChecker(std::string p_tweet);
	~TweetChecker();
	std::string tweet();
	std::string tweet(std::string p_tweet);
private:
	void initializeTweetMap();
	std::string matchTweetToEquivalentAcronym();
	std::string processTweetPossibleEquivalent();
	std::string m_tweet;
	std::string m_tweetAcronym;
	std::map<std::string, std::string> m_tweetMap;
};

#endif //TWEET_CHECKER_HPP 


tweetChecker.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "tweetChecker.hpp"

TweetChecker::TweetChecker() : m_tweet(""), m_tweetAcronym("")
{
	initializeTweetMap();
}

TweetChecker::TweetChecker(std::string p_tweet) : m_tweet(p_tweet), m_tweetAcronym("")
{
	initializeTweetMap();
}

TweetChecker::~TweetChecker()
{
	//BODY
}

std::string TweetChecker::tweet()
{
	return (m_tweet == "") ? "You have nothing to tweet..." : matchTweetToEquivalentAcronym();
}

std::string TweetChecker::tweet(std::string p_tweet)
{
	m_tweet = p_tweet;
	return (p_tweet == "") ? "You have nothing to tweet..." : matchTweetToEquivalentAcronym();
}

void TweetChecker::initializeTweetMap()
{
    m_tweetMap.insert(std::pair<std::string, std::string>("BFN", "Bye For Now"));
    m_tweetMap.insert(std::pair<std::string, std::string>("BTW", "By The Way"));
    m_tweetMap.insert(std::pair<std::string, std::string>("FTW", "For The Win"));
    m_tweetMap.insert(std::pair<std::string, std::string>("IRL", "In Real Life"));
    m_tweetMap.insert(std::pair<std::string, std::string>("ILY", "I Love You"));
    m_tweetMap.insert(std::pair<std::string, std::string>("LOL", "Laugh Out Loud"));
    m_tweetMap.insert(std::pair<std::string, std::string>("OMG", "Oh My Gosh"));
    m_tweetMap.insert(std::pair<std::string, std::string>("TWB", "The World Book"));
    m_tweetMap.insert(std::pair<std::string, std::string>("WTB", "What The Beast"));
}

std::string TweetChecker::matchTweetToEquivalentAcronym()
{
	std::map<std::string, std::string>::iterator tweetMapIterator = m_tweetMap.find(m_tweet);
	m_tweetAcronym = (tweetMapIterator != m_tweetMap.end()) ? tweetMapIterator->second : processTweetPossibleEquivalent();
    return m_tweetAcronym;
}

std::string TweetChecker::processTweetPossibleEquivalent()
{
	std::map<std::string, std::string>::iterator tweetMapIterator;
	std::string tweetContainer = m_tweet;
	std::string tweetAcronymContainer = "";
	int matchCount = 0;

	std::sort(tweetContainer.begin(), tweetContainer.end());
	do
	{
		tweetMapIterator = m_tweetMap.find(tweetContainer);
		if(tweetMapIterator != m_tweetMap.end())
		{
			if(++matchCount > 1)
			{
				tweetAcronymContainer += " or ";
			}
			tweetAcronymContainer += "Do you mean " + tweetMapIterator->first + "? " + tweetMapIterator->second;
		}
	}
	while(std::next_permutation(tweetContainer.begin(), tweetContainer.end()));

	if(matchCount == 0)
	{
		tweetAcronymContainer = m_tweet + " is not available in the Tweet library.";
	}
	return tweetAcronymContainer;
}
> I use the next_permutation to check for the spelling

Yes, +1. This takes care of transpositions.

Levenshtein distance looks for removal, insertion and substitution; but it does not account for transpositions.
https://en.wikipedia.org/wiki/Edit_distance

A version that uses edit distance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <cctype>

std::map< std::string, std::string > make_map()
{
    return {
               { "LOL", "laughing out loud" },
               { "BFN", "bye for now" },
               { "FTW", "for the win" },
               // ...
           } ;
}

// simple edit distance (does not look for transpositions)
// https://en.wikipedia.org/wiki/Edit_distance (brute force implementation)
std::size_t levenshtein_distance( const std::string& a, const std::string& b )
{
    if( a.empty() ) return b.empty() ? 0 : b.size() ;
    if( b.empty() ) return a.size() ;

    std::string as { a.begin(), a.end()-1 } ;
    std::string bs { b.begin(), b.end()-1 } ;

    return std::min( {
                         levenshtein_distance( as, b ) + 1,
                         levenshtein_distance( a, bs ) + 1,
                         levenshtein_distance( as, bs ) + ( a.back() != b.back() )
                     } ) ;
}

std::pair< std::string, std::string > split_punct( const std::string& str )
{
    auto iter = str.rbegin() ;
    while( iter != str.rend() && std::ispunct(*iter) ) ++iter ;
    return { { str.begin(), iter.base() }, { iter.base(), str.end() } } ;
}

std::string decode( const std::map< std::string, std::string >& map, const std::string& str )
{
    auto str_punct = split_punct(str) ;
    for( char& c : str_punct.first ) c = std::toupper(c) ;

    auto iter = map.find(str_punct.first) ;
    if( iter != map.end() ) return iter->second + str_punct.second ;

    std::size_t min_distance = 3 ; // max distance of two for a valid suggestion
    std::string decoded = str ;
    for( const auto& pair : map )
    {
        const auto distance = levenshtein_distance( pair.first, str_punct.first ) ;
        if( distance < min_distance ) // if this is the closest match so far
        {
            min_distance = distance ;
            decoded = "did you mean '" + pair.first + "'? => " + pair.second + str_punct.second ;
        }
    }

    return decoded ;
}

int main()
{
    const auto map = make_map() ;

    for( std::string maybe_leet : { "LOL", "lola!", "LPL", "llo", "not-leet", "Bfn", "nbf...", "TWF!!" } )
        std::cout << maybe_leet << " => " << decode( map, maybe_leet ) << "\n\n" ;
}

http://coliru.stacked-crooked.com/a/4dc0fd457c4cd5e7
Topic archived. No new replies allowed.