Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
Albatrosso
0 / 0 / 1
Регистрация: 20.07.2017
Сообщений: 75
Завершенные тесты: 1
1

Проверить являются ли слова синонимами

05.08.2017, 20:26. Просмотров 1081. Ответов 4
Метки нет (Все метки)

Два слова называются синонимами друг друга, если они имеют похожие значения. Реализуйте следующие операции над словарём синонимов:
ADD word1 word2 — добавить в словарь пару синонимов (word1, word2).
COUNT word — узнать количество синонимов слова word.
CHECK word1 word2 — проверить, являются ли слова word1 и word2 синонимами. Слова word1 и word2 считаются синонимами, если среди запросов ADD был хотя бы один запрос ADD word1 word2 или ADD word2 word1.
Формат ввода
Сначала вводится количество запросов Q, затем Q строк с описаниями запросов. Гарантируется, что в каждом запросе CHECK и ADD слова word1 и word2 различны. Все слова состоят лишь из латинских букв, цифр и символов подчёркивания.
Формат вывода
Для каждого запроса в соответствующей строке выведите ответ на него:
В ответ на запрос COUNT word выведите единственное целое число — количество синонимов слова word.
В ответ на запрос CHECK word1 word2 выведите строку YES, если word1 и word2 являются синонимами, и NO в противном случае.
Пример
Ввод
C++
1
2
3
4
5
6
7
8
9
8
ADD program code
COUNT cipher
ADD code cipher
COUNT code
COUNT program
CHECK code program
CHECK program cipher
CHECK cpp java
Вывод
C++
1
2
3
4
5
6
0
2
1
YES
NO
NO


а вот мое решение. Проблема заключается в том. что для последней команды вводе у меня не выводится требуемое NO, вместо этого программа заканчивает работу.
C++
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
#include <map>
#include <string>
#include <iostream>
#include <set>
using namespace std;
 
 
 
 
int main()
{
    int q;
    cin >> q;
    string command;
    map <string, string> v;
    set <string> b;
    set <string> n;
    for (q; q > 0; q--) {
        cin >> command;
        if (command == "ADD") {
            string word1, word2;
            
            cin >> word1 >> word2;
            v[word1] = word2;
            for (const auto& z : v) {
                b.insert(z.first);
                n.insert(z.second);
                
                
            }
                
 
             
        }else if (command == "COUNT") {
            string word;
            cin >> word;
            b.count(word);
            n.count(word);
            int r = b.count(word)+ n.count(word);
            cout << r << endl;
 
        } 
         else if (command == "CHECK") {
            string word3, word4;
            cin >> word3 >> word4;
            for (auto i : v) {
                if ((i.first == word3 && i.second == word4) || (i.first == word4 && i.second == word3)) {
                    cout << "YES" << endl;
                }
                else if ( i.first != word3 && i.second == word4 || i.first != word4 && i.second == word3 ){
                    cout << "NO" << endl;
                    if (b.count(word3) + n.count(word3) == 0 && b.count(word4) + n.count(word4) == 0) {
                        cout << "NO" << endl;
                    }
                }
            }
    }
 
 
}
    return 0;
}
Если в коде присутствует куча лишних элементов или конструкций, которые можно было бы упростить, не судите строго я пока только учусь, но буду рад, если подскажите как можно код оптимизировать.
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.08.2017, 20:26
Ответы с готовыми решениями:

Ввести с клавиатуры два слова. Проверить, являются ли они анаграммами
Ввести с клавиатуры два слова. Проверить, являются ли они анаграммами, то есть возможно ли из всех...

Проверить, являются ли слова анаграммами
Привет всем. Помогите, пожалуйста, написать программу на языке Си. Задание: Пользователь...

Проверить, являются ли заданные слова в предложении палиндромами
Проверить, являются ли заданные слова в предложении палиндромами (перевёртышами).

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

Заменить в файле слова синонимами
даны 2 текстовых файла f1 и f2 файл f1 содержит произольный текст. слова в файле разделены...

4
DevAlone
324 / 276 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
Завершенные тесты: 4
06.08.2017, 00:05 2
Как-то так:
C++
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <iostream>
#include <map>
#include <set>
 
#include <typeinfo>
 
class WordsDatabase {
    using WordPointer = std::string const*;
 
public:
    WordsDatabase()
    {
    }
 
    WordPointer insertWord(const std::string& word)
    {
        return &(*words.insert(word).first);
    }
 
    void makeWordsSynonyms(const std::string& word1, const std::string& word2)
    {
        WordPointer p1 = insertWord(word1);
        WordPointer p2 = insertWord(word2);
 
        {
            auto it = synonyms.find(p1);
            if (it == synonyms.end()) {
                std::set<WordPointer> set;
                set.insert(p2);
                synonyms.insert(std::make_pair(p1, set));
            } else {
                it->second.insert(p2);
            }
        }
 
        {
            auto it = synonyms.find(p2);
            if (it == synonyms.end()) {
                std::set<WordPointer> set;
                set.insert(p1);
                synonyms.insert(std::make_pair(p2, set));
            } else {
                it->second.insert(p1);
            }
        }
    }
 
    bool isWordsSynonyms(const std::string& word1, const std::string& word2)
    {
        WordPointer p1 = getWordIndex(word1);
        WordPointer p2 = getWordIndex(word2);
 
        if (!p1 || !p2)
            return false;
 
        auto it = synonyms.find(p1);
        if (it == synonyms.end())
            return false;
 
        return it->second.find(p2) != it->second.end();
    }
 
    void debug()
    {
        std::cout << "words: " << std::endl;
        for (auto& word : words)
            std::cout << word << " (" << &word << ")" << std::endl;
        std::cout << std::endl;
 
        std::cout << "synonyms: " << std::endl;
        for (auto& pair : synonyms) {
            std::cout << pair.first << ": ";
            for (auto& value : pair.second) {
                std::cout << value << ", ";
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;
    }
 
private:
    std::set<std::string> words;
    std::map<WordPointer, std::set<WordPointer>> synonyms;
 
    WordPointer getWordIndex(const std::string& word)
    {
        auto it = words.find(word);
        if (it == words.end())
            return nullptr;
        return &(*it);
    }
};
 
int main()
{
    WordsDatabase db;
 
    db.makeWordsSynonyms("car", "truck");
    db.makeWordsSynonyms("bicycle", "bike");
    db.makeWordsSynonyms("programmer", "freak");
    db.makeWordsSynonyms("beautiful", "lovely");
    db.makeWordsSynonyms("beautiful", "lovely");
    db.makeWordsSynonyms("beautiful", "fine");
    db.makeWordsSynonyms("beautiful", "nice");
    db.insertWord("something");
 
    std::cout << db.isWordsSynonyms("truck", "car") << std::endl;
    std::cout << db.isWordsSynonyms("car", "bike") << std::endl;
    std::cout << db.isWordsSynonyms("beautiful", "fine") << std::endl;
    std::cout << db.isWordsSynonyms("something", "bike") << std::endl;
 
    return 0;
}
0
Albatrosso
0 / 0 / 1
Регистрация: 20.07.2017
Сообщений: 75
Завершенные тесты: 1
06.08.2017, 14:03  [ТС] 3
Так, пока, честно говоря, я и половины не в состоянии до конца понять. Спасибо за ваши варианты, вижу , что мой код самое примитивное, что можно к этой задаче придумать. Но все-таки, можно ли мой код доработать таким образом, чтобы вывод соответствовал заданному.
0
DevAlone
324 / 276 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
Завершенные тесты: 4
06.08.2017, 15:45 4
Лучший ответ Сообщение было отмечено Albatrosso как решение

Решение

Цитата Сообщение от Albatrosso Посмотреть сообщение
Так, пока, честно говоря, я и половины не в состоянии до конца понять
C++
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
#include <map>
#include <set>
 
// класс, почитай тут например, если не знаешь, что это [url]http://cppstudio.com/post/439/[/url]
class WordsDatabase {
// объявляем синоним для типа std::string const *, т.е. когда будем писать WordPointer, это эквивалентно std::string const*
// std::string const* - указатель на const std::string, т.е. содержит адрес по которому расположена строка
    using WordPointer = std::string const*;
 
public:
    WordsDatabase()
    {
    }
 
    WordPointer insertWord(const std::string& word)// передача по ссылке для экономии ресурсов
    {
// words.insert(word) - вставляем word в std::set 
// .first получаем итератор на результат
// * - разыменовываем итератор, получая ссылку на только что вставленную сторку
// & - получаем адрес этой строки 
        return &(*words.insert(word).first);
    }
 
    void makeWordsSynonyms(const std::string& word1, const std::string& word2)
    {
        WordPointer p1 = insertWord(word1);
        WordPointer p2 = insertWord(word2);
 
        {
// находим слово в мапе синонимов
            auto it = synonyms.find(p1);
            if (it == synonyms.end()) {
// если не нашли, вставляем новое значение
                std::set<WordPointer> set;
                set.insert(p2);
                synonyms.insert(std::make_pair(p1, set));
            } else {
// если нашли, просто добавляем ещё один синоним 
                it->second.insert(p2);
            }
        }
 
        {
// тоже самое, только наоборот, ищем теперь не первое, а второе слово
            auto it = synonyms.find(p2);
            if (it == synonyms.end()) {
                std::set<WordPointer> set;
                set.insert(p1);
                synonyms.insert(std::make_pair(p2, set));
            } else {
                it->second.insert(p1);
            }
        }
    }
 
    bool isWordsSynonyms(const std::string& word1, const std::string& word2)
    {
// ищем слова в words
        WordPointer p1 = getWordIndex(word1);
        WordPointer p2 = getWordIndex(word2);
 
// функция getWordIndex возвращаем nullptr, если слово не нашлось
        if (!p1 || !p2)
            return false;
 
// ищем word1 в мапе синонимов
        auto it = synonyms.find(p1);
        if (it == synonyms.end())
            return false;
 
// если нашли, ищем в std::set<WordPointer> word2 и возвращаем true, если оно там есть
        return it->second.find(p2) != it->second.end();
    }
 
// просто функция для отладки, показывающая содержимое котейнеров
    void debug()
    {
        std::cout << "words: " << std::endl;
        for (auto& word : words)
            std::cout << word << " (" << &word << ")" << std::endl;
        std::cout << std::endl;
 
        std::cout << "synonyms: " << std::endl;
        for (auto& pair : synonyms) {
            std::cout << pair.first << ": ";
            for (auto& value : pair.second) {
                std::cout << value << ", ";
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;
    }
 
private:
// множество строк
    std::set<std::string> words;
// std::map, который хранит соответствие адреса строки и множества из адресов других строк(синонимы)
// адреса используются для экономии памяти
    std::map<WordPointer, std::set<WordPointer>> synonyms;
 
    WordPointer getWordIndex(const std::string& word)
    {
        auto it = words.find(word);
        if (it == words.end())
            return nullptr;
        return &(*it);
    }
};
 
int main()
{
    WordsDatabase db;
 
    db.makeWordsSynonyms("car", "truck");
    db.makeWordsSynonyms("bicycle", "bike");
    db.makeWordsSynonyms("programmer", "freak");
    db.makeWordsSynonyms("beautiful", "lovely");
    db.makeWordsSynonyms("beautiful", "lovely");
    db.makeWordsSynonyms("beautiful", "fine");
    db.makeWordsSynonyms("beautiful", "nice");
    db.insertWord("something");
 
    std::cout << db.isWordsSynonyms("truck", "car") << std::endl;
    std::cout << db.isWordsSynonyms("car", "bike") << std::endl;
    std::cout << db.isWordsSynonyms("beautiful", "fine") << std::endl;
    std::cout << db.isWordsSynonyms("something", "bike") << std::endl;
 
    return 0;
}
Добавлено через 17 минут
Цитата Сообщение от Albatrosso Посмотреть сообщение
Но все-таки, можно ли мой код доработать таким образом, чтобы вывод соответствовал заданному.
Твой код абсолютно не читаем, не используй однобуквенные переменные, переделал так, чтобы не слишком усложнить:
C++
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
#include <iostream>
#include <map>
#include <set>
#include <string>
 
using std::cout;
using std::cin;
using std::endl;
using std::string;
 
int main()
{
    int commandsCount;
    cin >> commandsCount;
    std::map<string, std::set<string>> synonyms;
 
    string command;
 
    for (; commandsCount > 0; commandsCount--) {
        cin >> command;
        if (command == "ADD") {
            string word1, word2;
            cin >> word1 >> word2;
 
            synonyms[word1].insert(word2);
            synonyms[word2].insert(word1);
        } else if (command == "COUNT") {
            string word;
            cin >> word;
            size_t synonymsCount;
 
            auto it = synonyms.find(word);
            // если нашли
            if (it != synonyms.end())
                synonymsCount = it->second.size();
            else
                synonymsCount = 0;
 
            cout << synonymsCount << endl;
 
        } else if (command == "CHECK") {
            string word1, word2;
            cin >> word1 >> word2;
 
            bool isSynonyms = false;
 
            auto it = synonyms.find(word1);
            if (it != synonyms.end())
                if (it->second.find(word2) != it->second.end())
                    isSynonyms = true;
 
            cout << (isSynonyms ? "TRUE" : "FALSE") << endl;
        }
    }
    //    return 0; // в C++ это необязательно
}
Тест в первом посте проходит
1
Albatrosso
0 / 0 / 1
Регистрация: 20.07.2017
Сообщений: 75
Завершенные тесты: 1
06.08.2017, 16:02  [ТС] 5
Спасибо! Будет над чем подумать!
0
06.08.2017, 16:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.08.2017, 16:02

Проверить, являются ли слова правильной записью передвижений шахматного слона
Здравствуйте! Дали задачу на строки, в условии сказано что можно использовать только тип char для...

Проверить, являются ли данные два слова обращенными друг к другу
Проверить, являются ли данные два слова обращенными друг к другу, то есть первое читается слева...

Заменить в файле те слова, которые можно, их синонимами
Даны два текстовых файла f1 и f2. Файл f1 содержит произвольный текст. Слова в тексте разделены...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru