Использование векторов для звукового сигнала некоторых предопределенных строк

Итак, в настоящее время я выполняю упражнения из моей книги по программированию «Программирование: принципы и практика использования С++» от Бьярна Страуструпа, и в настоящее время я застрял на одном упражнении. По сути, упражнение состоит в том, чтобы написать программу, которая выдает слова, которые ей не нравятся. Это работает так: пользователь вводит строку, а программа повторяет слово. Если слово, которое вводит пользователь, является частью вектора неприязни, слово заменяется на «Bleep». (Я не знаю, правильно ли я объяснил это, но это не должно быть сложно понять).

Это моя версия программы:

int main()
{
    string dislike = "Potato";
    string words = " ";

    cout << "Please enter some words: " << endl;
    while(cin>>words)
    {
        if(words==dislike)
        {
            cout << "Bleep!" << endl;
        }

        else
        {
            cout << words << endl;
        }
    }
    system("pause");
    return 0;
}

Как видите, в этой версии не используются векторы (а так и должно быть, потому что упражнение идет сразу после объяснения векторов в главе). Итак, мой вопрос: как я могу реализовать вектор со многими словами «не нравится» в нем следующим образом:

vector<string>dislike;
dislike.push_back("Potatoes");
dislike.push_back("Peanuts");
dislike.push_back("Coconut");

и сделать так, чтобы он работал, как моя другая версия без векторов (повторяет слова, но пищит слова, которые не нравятся). Кажется, я не понимаю, как перемещаться по вектору, чтобы он только пищал слова «не нравится».

Если бы кто-нибудь мог помочь мне и объяснить, как это работает (пожалуйста, не просто дайте мне ответ), я был бы очень признателен.

Спасибо за ваше время и помощь, изучение С++ в одиночку не всегда просто, и я благодарю этот веб-сайт за то, что он немного облегчил мою кривую обучения.

бобикул


person Raphael    schedule 28.04.2011    source источник


Ответы (8)


Хорошо, позвольте мне объяснить простой подход к этому. Есть более элегантные, но сейчас важно, чтобы вы поняли, как можно получить доступ к std::vector и как правильно составить управляющие структуры.

Шаг 1 - перебор всех элементов вектора

Вы можете использовать итераторы для просмотра всех элементов вектора.

for(vector<string>::const_iterator it = dislike.begin(); it != dislike.end(); ++it) {

   // now *it gives access to the current element (here: current dislike word)
   if (*it == words) {
       // ... yeah, we found out the current word is on the list!
   }         
}

Вы получаете итератор для первого элемента вектора, вызывая begin(), а затем продолжаете увеличивать его (++it), пока не достигнете конца вектора. Я использую const_iterator здесь, потому что я не собираюсь изменять какие-либо элементы, если вам нужно, используйте iterator.

с std::vector также возможна индексация через [index] (но обычно не рекомендуется):

for(size_t i = 0;i < dislike.size(); ++i) {
   // dislike[i] is the current element

   if (dislike[i] == words) {
      // huuuuray! another BEEEP candidate
   }
}

Шаг 2 — пораньше разорвите петлю

Как только вы точно знаете, что у нас есть нелюбимое слово, вам не нужно искать вектор дальше.

for(vector<string>::const_iterator it = dislike.begin(); it != dislike.end(); ++it) {   
  if (*it == words) {
     // we found a positive match, so beep and get out of here
     cout << "Bleep!" << endl;
     break;
  }         
}

Шаг 3 — отметьте, если мы уже обработали слово

bool is_beep = false;
for(vector<string>::const_iterator it = dislike.begin(); it != dislike.end(); ++it) {   
  if (*it == words) {
     // we found a positive match, so beep and get out of here
     cout << "Bleep!" << endl;
     is_beep = true;
     break;
  }         
}
// this is not a dislike word if is_beep is false, so print it as usual
if (!is_beep) {
   cout << words << endl;
}

Шаг 4 — собираем все вместе

int main()
{
    vector<string>dislike;
    dislike.push_back("Potatoes");
    dislike.push_back("Peanuts");
    dislike.push_back("Coconut");
    string words = " ";

    cout << "Please enter some words: " << endl;
    while(cin>>words)
    {
        bool is_beep = false;
        for(vector<string>::const_iterator it = dislike.begin(); it != dislike.end(); ++it) {   
           if (*it == words) {
            // we found a positive match, so beep and get out of here
            cout << "Bleep!" << endl;
            is_beep = true;
            break;
          }         
        }
       // this is not a dislike word if is_beep is false, so print it as usual
       if (!is_beep) {
            cout << words << endl;
       }
    }
    system("pause");
    return 0;
}

Посмотрите std::find, чтобы найти более идиоматичное решение — оно практически избавит вас от внутреннего цикла. Вы также можете избавиться от этого bool в последнем примере кода, если немного реструктурируете. Я оставлю это вам в качестве упражнения (подсказка: держите итератор в рабочем состоянии и проверяйте его значение после завершения цикла).

person Alexander Gessler    schedule 28.04.2011
comment
В то время как ответы после вас имеют более простой подход, я выбрал ваш ответ в качестве окончательного ответа, потому что вы нашли время, чтобы шаг за шагом объяснить, как решить проблему. Большое спасибо =) - person Raphael; 28.04.2011
comment
Но я никогда раньше не видел оператора it, могу ли я получить больше пояснений по этому поводу? - person Raphael; 28.04.2011
comment
Это не оператор - это имя переменной, инициализированное здесь: for(vector<string>::const_iterator it = dislike.begin(). - person Alexander Gessler; 28.04.2011
comment
Посмотрите cprogramming.com/tutorial/stl/iterators.html для больше информации об итераторах. - person Alexander Gessler; 28.04.2011

int main()
{
    vector<string> dislike;
    dislike.push_back("Potatoes");
    dislike.push_back("Peanuts");
    dislike.push_back("Coconut");
    string words;

    cout << "Please enter some words: " << endl;
    while(cin >> words)
    {
        if(find(dislike.begin(), dislike.end(), words) != dislike.end())
        {
            cout << "Bleep!" << endl;
        }

        else
        {
            cout << words << endl;
        }
    }
    system("pause");
    return 0;
}

Для std::find добавьте #include <algorithm> к вашему источнику.

person Mihran Hovsepyan    schedule 28.04.2011
comment
-1 На какую часть пожалуйста не дай мне сразу ответ ты не понял? - person Chris Jester-Young; 28.04.2011
comment
Этот код не нуждается в пояснениях, потому что: 1. это тот же код, что и в сообщении ОП в его вопросе, просто добавлено std::find. 2. Думаю, совершенно ясно, что здесь нужно найти. Я не думаю, что мой ответ настолько фиктивен или бесполезен, чтобы получить отрицательный голос. - person Mihran Hovsepyan; 28.04.2011
comment
Я согласен, я бы хотел, чтобы кто-то рассказал мне об этих методах раньше, потому что все страдают от ошибок поиска в контейнере. - person Eric Fortin; 28.04.2011

используйте std::find(your_vector.begin(), your_vector.end(), words)

int main()
{
    vector<string>dislike;
    dislike.push_back("Potatoes");
    dislike.push_back("Peanuts");
    dislike.push_back("Coconut");
    string words = " ";

    cout << "Please enter some words: " << endl;
    while(cin>>words)
    {
        if(std::find(dislike.begin(), dislike.end(), words) != dislike.end())
        {
            cout << "Bleep!" << endl;
        }

        else
        {
            cout << words << endl;
        }
    }
    system("pause");
    return 0;
}
person Eric Fortin    schedule 28.04.2011
comment
-1 На какую часть пожалуйста не дай мне сразу ответ ты не понял? - person Chris Jester-Young; 28.04.2011

Вот мое решение этого конкретного вопроса в книге, когда я ее читал. :) надеюсь, что это говорит само за себя.

/*THE QUESTION GOES LIKE;
Write a program that “bleeps” out words that you don’t like; that is, you read in words    
using cin and print them again on cout. If a word is among a few you have defined, you
write out BLEEP instead of that word. Start with one “disliked word” such as string
disliked = “Broccoli”; 
When that works, add a few more.*/



#include "std_lib_facilities.h"  // this is a standard library header that came with 
the book

int main () {
vector<string> dislike = {"Dislike", "Alike", "Hello", "Water"};   /* defining a vector  
for the disliked words. */

vector<string> words;  //initializing vector for the read words.

cout << "Please enter some words\n";   //prompt user to enter some words.

for( string word; cin >> word;)  //this current word typed is read in.

    words.push_back(word);   // word read in are pushed into the vector "words".

sort(words);  /* function for the standard library for sorting data...this makes the data from the vector "words" appears in alphabetical order. */

for (int i=0; i<words.size(); ++i){   /*this acts as an iterator. and goes through all the element of the vector "words".  */

    if(i==0 || words[i-1]!=words[i]){   /*this prevents the words from repeating....just an option incase the user enters same kinda words twice or more. */

        if(words[i]!=dislike[0] && words[i]!=dislike[1] && words[i]!=dislike[2] && words[i]!=dislike[3])  /*This test checks whether the words typed match any of the elements of the vector "dislike".if they don't match;   */

            cout << words[i]<< '\n';  //prints out the words.
        else
            cout << "BlEEP!\n";   //if they match....print out "BlEEP!".
       }
   }


}
person user3741332    schedule 14.06.2014

Я изучаю С++. Эта Программа была несколько изменена. Напишите программу, которая "пищит" плохие слова, которые вам не нравятся; то есть вы читаете слова с помощью cin и снова печатаете их с помощью cout. Если слово находится среди нескольких определенных вами слов, вы пишете BLEEP и/или используете его в BLEEP(Sound) вместо этого слова. Начните с одного "плохого слова", такого как -- string badword = "arse"; Когда это сработает, добавьте еще несколько или напишите целую программу, основанную на всех плохих словах, которые вы не хотите распечатывать.

while (cin >> words)
{
    if(find(badwords.begin(), badwords.end(),words) !=badwords.end())
    {
        cout << "      " << endl; // You can put Bleep in or leave it out (Blank) if blank
                                  // it will leave a blank in the phrase when it prints
        Beep(523,500);            // This is to Bleep (Sound) when a bad word is found
        cin.get();                
    }
    else
    {
        cout << words << endl;
    }
}

Поскольку кто-то дал ответ, я немного изменил программу. Это для вас, чтобы учиться. Это работает на Visual Studio Express 2012

person dakkar19    schedule 11.04.2015

Я решил эту проблему, используя идеи, которые уже были изучены в предыдущих главах, не выходя за рамки того, что вы понимаете.

#include <iostream>
#include <vector>

using namespace std;

int main()
{ 

vector<string> disliked;

//adding disliked words to the vector

disliked.push_back("dog");
disliked.push_back("cat");
disliked.push_back("goat");
disliked.push_back("cow");
disliked.push_back("sheep");
disliked.push_back("pig");


string words=""; //this variable will store the input from the user.

while(cin>>words)
    {//test every entered word to see if it's equal to any word listed in   disliked words.
        if(words==disliked[0] ||//or
           words==disliked[1] ||//or
           words==disliked[2] ||//or
           words==disliked[3] ||//or
           words==disliked[4] ||//or
           words==disliked[5]){
                               cout<<"Bleeps";}
        else{
             cout<<words;}
}
return 0;
//Not that I have not gone beyond what has been covered in the previous chapters.
//I know their are beautiful solutions to this problem. 
//Keep learning you will know everything.

}

person Sadiki    schedule 19.07.2016

Этот вопрос был задан давным-давно, поэтому автор, вероятно, профессионал в этом вопросе, лол, но вот более простое, но работающее решение для всех, кто ищет тот же ответ. Я учусь с самого начала через книгу Бьярне, поэтому я еще не «затронут» высшими знаниями, чтобы сбить вас с толку, но с решениями, которые достаточно хороши, чтобы работать, основываясь на том, как далеко мы продвинулись в книге. :)

// program that bleeps out words we dont like

vector <string> words;
vector <string> bwords = {"this", "that", "then"}; //bleeped words
string sword; // temporary word

cout << "Enter few words: ";
for (string tword; cin >> tword;)  // read in words
    words.push_back(tword);

//check if they match beeped words

cout << "\n\nWords:\n";
for (int i = 0; i < words.size(); i++)    //take word[i] from the vector
{  
    sword = words[i];    // temporary variable is now word[i]
    for (int j = 0; j < bwords.size(); j++)   // take beeped word[j] from saved words
    {
            if (words[i] == bwords[j]) // is word[i] same as bleeped word[j]
            sword = "BLEEP";  // if word[i] is same then replace sword with BEEP
    }

    cout << sword << "\n"; // now we checked first word and if it matches with any of the bleeped words then it will cout bleep, otherwise it will cout first word.
}

Теперь в этом примере вы можете добавить много новых звуковых слов, и вам не нужно будет менять код. Это не лучшее решение в «реальном» программировании, но на этом этапе книги мы узнали о, если, векторе (не так много), cout, cin и т. д., так что все остальное выглядит запутанным. на данный момент мы еще не знаем об использовании :: , begin, true/fals, cin.get или что-то в этом роде.

person Tina Surname    schedule 22.06.2019

«Простое может быть сложнее, чем сложное: вам нужно много работать, чтобы очистить свое мышление, чтобы сделать его простым. Но в конце концов это того стоит, потому что, попав туда, вы сможете свернуть горы». - Стив Джобс

#include "std_lib_facilities.h"

int main()
{
    

    vector<string>disliked;

    disliked.push_back("Apple"); 
    disliked.push_back("OliveOil");
    disliked.push_back("Strawberry");
    disliked.push_back("Lemon");
    
    cout<<"Please type some words:"<<"\n";
    string words=" ";
    while(cin>>words)
    
    {
        if (words==disliked[0] | words==disliked[1]|
            words==disliked[2] | words==disliked[3])
            
        {cout<<"BLEEP"<<"\n";}
    
      else{cout<<words<<"\n";}
    }

    keep_window_open();
}
person Carter Q    schedule 18.08.2020