Количество слов с сортировкой C ++ - PullRequest
0 голосов
/ 10 октября 2019

У меня вопрос к классу структуры данных. Я совершенно не знаю, как с этим справиться, кто-нибудь может дать несколько советов, пожалуйста?

  1. Как остановить программу и убедиться, что вывод выводится правильно?
  2. Нужно ли мнеиметь дело с картированием?

вопросник, который я получил от профессора

Вот мой пример кодирования:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string s [100];

    for (int i = 0; i < 100; i++) {
        cin >> s[i];
        s[i] = Sort(s[i], s[i+1]);
    }


    //check the number of time the words repeatcout the answer
    for (int i = 0; i < 100; i++) {
        cout << s[i] << count (s[i],s[i+1]) <<endl;
    }
    return 0;
}


string Sort(string current, string next ) {
    if (current > next) {
        string temp = current;
        current = next;
        next = temp;
    }
    else {
        return current;
    }
}

int count(string word, string Nextword) {
    int count;
    if (word == Nextword) {
        count++;
    }
    else {
        return count;
    }
}

Ответы [ 4 ]

1 голос
/ 10 октября 2019

Вместо того, чтобы пытаться использовать базовый массив строк, вам понадобится какой-то способ отслеживать количество раз, которое видно каждое слово. Вы можете использовать простой struct или std::map. В любом случае вы можете связать слово и количество раз, которое оно рассматривается как один объект. Если вы затем соберете всю структуру, содержащую слово и число в std::vector, в отличие от базового массива, вы можете предоставить простую функцию сравнения, чтобы использовать std::sort для сортировки вектора по слову, сохраняя при этом связь счетчика скаждое слово.

Используя подход stuct, вы можете создать структуру, содержащую std::string и счетчик, такой как:

 struct wordcount {      /* struct holding word and count */
    std::string word;
    size_t count;
};

Для функции сравнениячтобы отсортировать вектор wordcount по word, вы можете использовать простое:

/* compare function to sort vector of struct by words */
bool cmp (const wordcount& a, const wordcount& b)
{
    return a.word < b.word;
}

Используя структуру, вам нужно будет перебрать слова, которые вы видели до сих пор, чтобы определить, просто ли вынеобходимо увеличить count на существующем слове или добавить новую структуру wordcount к вашему вектору с помощью count = 1;. Чтобы сделать функцию полезной, вы можете сделать так, чтобы она возвращала индекс в векторе (слабо эквивалентный индексув массиве), если слово уже существует, или верните -1, если его нет.

/* interate over each struct in vector words to find word */
int findword (const std::vector<wordcount>& words, 
                const std::string& word)
{
    for (auto w = words.begin(); w != words.end(); w++)
        if (w->word == word)            /* if word found */
            return w - words.begin();   /* return index */

    return -1;  /* return word not found */
}

На основе возврата вы можете либо увеличить count в индексе, либодд новый wordcount в ваш вектор. Короткая реализация, использующая вышеизложенное, будет выглядеть так:

int main (int argc, char **argv) {

    if (argc < 2) { /* validate filename given as argument */
        std::cerr << "error: insufficient input.\n"
                << "usage: " << argv[0] << "<filename>\n";
        return 1;
    }

    std::string word;                   /* string to hold word */
    std::vector<wordcount> words {};    /* vector of struct wordcount */
    std::fstream f (argv[1]);           /* file stream */

    while (f >> word) {                 /* read each word from file */
        int idx = findword (words, word);   /* alread exists, get index */
        if (idx != -1) {                /* if index found */
            words[idx].count++;         /* increment count */
        }
        else {  /* otherwise new word */
            wordcount tmp = {word, 1};  /* initialize struct */
            words.push_back(tmp);       /* add to vector */
        }
    }

    std::sort (words.begin(), words.end(), cmp);    /* sort by words */

    for (auto& w : words)   /* output results */
        std::cout << w.word << " " << w.count << '\n';
}

Если сложить все вышеперечисленные части вместе, вы получите:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

struct wordcount {      /* struct holding word and count */
    std::string word;
    size_t count;
};

/* compare function to sort vector of struct by words */
bool cmp (const wordcount& a, const wordcount& b)
{
    return a.word < b.word;
}

/* interate over each struct in vector words to find word */
int findword (const std::vector<wordcount>& words, 
                const std::string& word)
{
    for (auto w = words.begin(); w != words.end(); w++)
        if (w->word == word)            /* if word found */
            return w - words.begin();   /* return index */

    return -1;  /* return word not found */
}

int main (int argc, char **argv) {

    if (argc < 2) { /* validate filename given as argument */
        std::cerr << "error: insufficient input.\n"
                << "usage: " << argv[0] << "<filename>\n";
        return 1;
    }

    std::string word;                   /* string to hold word */
    std::vector<wordcount> words {};    /* vector of struct wordcount */
    std::fstream f (argv[1]);           /* file stream */

    while (f >> word) {                 /* read each word from file */
        int idx = findword (words, word);   /* alread exists, get index */
        if (idx != -1) {                /* if index found */
            words[idx].count++;         /* increment count */
        }
        else {  /* otherwise new word */
            wordcount tmp = {word, 1};  /* initialize struct */
            words.push_back(tmp);       /* add to vector */
        }
    }

    std::sort (words.begin(), words.end(), cmp);    /* sort by words */

    for (auto& w : words)   /* output results */
        std::cout << w.word << " " << w.count << '\n';
}

Пример использования / Вывод

Если вы используете образец ввода, вы получите.

$ ./bin/wordcount dat/webpage.txt
Computer 1
algorithm 1
analysis 1
and 1
computer 3
department 1
design 2
quantum 1
science 1
system 1

Существует множество способов решить проблему этого типа. Это можно сделать с простыми старыми массивами, но тогда вы будете отслеживать слова и считать в каком-то отдельном массиве (или массивах), а затем либо написать свой собственный вид (или использовать C qsort в одном массиве, содержащем слова изатем сопоставьте счет обратно с отсортированным выводом с копией оригинала и вашего массива счетчиков). Ключ, независимо от используемого вами подхода, заключается в том, что у вас должен быть способ сохранить предварительную сортировку между словами и количество раз, которое они каждый видят с результатом пост-сортировки ваших слов, а затем способ отобразить обратные отсчеты. на правильное слово. Использование объекта, который связывает слово и считается как единое целое, решает проблему ассоциации.

Посмотрите вещи, примите их как один из способов приблизиться к нему. Дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 10 октября 2019

std :: map может выполнять сортировку и подсчет одновременно для вас:

#include <map>
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::string;

int main() {
  std::map<string,size_t> wordcount;
  for(string word;cin>>word;++wordcount[word]);
  for(auto it=wordcount.begin();it!=wordcount.end();++it)
    cout << it->first << " " << it->second << endl;
}
echo -ne "Computer system\ncomputer design\nalgorithm design and analysis\nquantum computer\ncomputer science department" | ./a.out
Computer 1
algorithm 1
analysis 1
and 1
computer 3
department 1
design 2
quantum 1
science 1
system 1
0 голосов
/ 10 октября 2019

Если использование STL не является опцией, что означает, что если вы не можете использовать вектор и т. Д., То это простое решение может помочь. Также в вашем коде вы объявили размер строкового массива равным 100, что, я думаю, вы сделали, потому что МАКСИМАЛЬНЫЙ размер массива не может быть принят в качестве входных данных в соответствии с вашей постановкой задачи.

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

Также я предлагаю вам узнать о STL в C ++, это также поможет вам в конкурентном кодировании.

    #include <iostream>
    using namespace std;

    //Forward declaration of functions 
    void sortStringArray(int index,string* s);
    void printWordCount(int index,string array[]);

    int main()
    {
        string s [100]; //considering maximum words will be upto 100 words
        string input;  //variable to keep track of each line input
        int index=0;   //index to keep track of size of populated array since we don't need to sort whole array of size 100 if it is not filled


        while (getline(cin, input) && !input.empty()){  //while line is not empty continue to take inputs
            string temp="";                     
            char previous=' ';                  
            for(int i=0;i<input.size();i++){            //loop to seperate the words by space or tab
                if(input[i]==' ' && previous!=' '){
                    s[index++]=temp;
                    temp="";
                }
                else if(input[i]!=' '){
                    temp+=input[i];
                }
                previous=input[i];
            }
            if(temp.size()!=0){
                s[index++] =temp;   
            }
        }

        //Step 1: sort the generated array by calling function with reference, thus function directly modifies the array and don't need to return anything
        sortStringArray(index,s);


        //Step 2: print each word count in sorted order
        printWordCount(index,s);


        return 0;
    }

    /*
    Function takes the "index" which is the size upto which array is filled and we need only filled elements
    Function takes stirng array by reference and uses Bubble Sort to sort the array
    */
    void sortStringArray(int index,string* s){
        for(int i=0;i<index-1;i++){
            for(int j=0;j<index-i-1;j++){
                if(s[j]>s[j+1]){
                    string temp=s[j];
                    s[j]=s[j+1];
                    s[j+1]=temp;
                }
            }
        }
    }


    /*
    Function takes the "index" which is the size upto which array is filled and we need only filled elements
    Function takes stirng array by reference and prints count of each word
    */
    void printWordCount(int index,string array[]){
        int count=1; //to keep track of the similar word count
        for(int i=0;i<index-1;i++){
            if(array[i]==array[i+1]){ //if current and upcoming words are same then increase the count
                count++;
            }
            else{                       //if next word is not equal to current word then print the count of current word and set counter to 1
                cout<<array[i]<<" "<<count<<endl;
                count=1;
            }
        }
        if(array[index-1]==array[index-2]){  //at end of array if the last and second last words were equal then print the count+1
            cout<<array[index-1]<<" "<<count+1<<endl;
        }
        else{                               //otherwise the count equal to the last count which will be "1"
            cout<<array[index-1]<<" "<<count;
        }
    }

Выход:

    Computer system
    computer design
    algorithm design and analysis
    quantum computer
    computer science department

    Computer 1
    algorithm 1
    analysis 1
    and 1
    computer 3
    department 1
    design 2
    quantum 1
    science 1
    system 1
    --------------------------------
    Process exited after 1.89 seconds with return value 0
0 голосов
/ 10 октября 2019

Скопируйте и вставьте этот код и проверьте с несколькими строками. Решение:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

vector<string> split(const string& i_str, const string& i_delim)
{
    vector<string> result;

    size_t found = i_str.find(i_delim);
    size_t startIndex = 0;

    while (found != string::npos)
    {
        string temp(i_str.begin() + startIndex, i_str.begin() + found);
        result.push_back(temp);
        startIndex = found + i_delim.size();
        found = i_str.find(i_delim, startIndex);
    }
    if (startIndex != i_str.size())
        result.push_back(string(i_str.begin() + startIndex, i_str.end()));
    return result;
}

void countFunc(vector<string> cal) {
    vector<pair<string, int>> result;
    for (int i = 0; i < cal.size(); i++)
    {
        string temp = cal[i];
        if (temp.empty())
        {
            continue;
        }
        int ncount = 1;
        int j = i+1;
        while(j < cal.size())
        {
            if (temp == cal[j])
            {
                ncount++;
                cal[j] = "";
            }
            j++;
        }
        result.push_back(make_pair(temp, ncount));
    }
    std::cout << "String\tCount\n";
    for (int i = 0; i < result.size(); i++)
    {
        cout << result[i].first << "\t" << result[i].second << endl;
    }
}

int main()
{
    vector<string> str;
    vector<string> res;
    printf("Enter the Number Line :");
    int size = 0;
    cin >> size;
    for (int i = 0; i < size+1; i++)
    {
        string s;
        getline(cin, s);
        if (s.empty())
        {
            continue;
        }
        else
        {
            str.push_back(s);
        }
    }
    for (int i = 0; i < size; i++)
    {
        vector<string> temp;
        temp = split(str[i], " ");
        res.insert(res.end(), temp.begin(), temp.end());
    }
    sort(res.begin(), res.end());
    countFunc(res);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...