3

「ウォークトーク、話せない、話せない」という文字列があります。繰り返された単語を数えて表示したい。注:大文字と小文字は区別されません。

私はデリメータを使用しました

strtok(string, ",.;:\"!? -_\n\t*()@#=+");

に保存しました

char *temp[100];

単語の繰り返しを確認するにはどうすればよいですか?そして、以下のように表示します

3 won't
2 talk
1 can't
1 walk

繰り返しが最も多いものから最も低いものへと表示されます。また、繰り返しが同じ場合は、アルファベット順に表示します。

英語が下手でごめんなさい。

4

4 に答える 4

3

std :: stringを使用して、の結果を保持しstrtok()ます。次にstd::map<string, int>、文字列(キー)が発生した回数を保持するaを作成します。

マップに次のものを入力できます。

std::map<string, int> myMap;
myMap[tokenizedWord]++; //Increase count of word.

次に、マップコンテンツを循環して、整数値が2より大きい場所で印刷できます。

for (std::map<string, int>::iterator iter = myMap.begin(); iter != myMap.end(); ++iter)
{
    if (iter->second > 1)
        std::cout << "Duplicated word: " << iter->first << " count = " << iter->second;
}

順番にトラバースする方法を説明します。値をベクトルなどに入れて、std::sort印刷などの前に使用できます。残念ながら、マップは連想コンテナであり、内部の順序が崩れるため、マップを並べ替えることはできません。

std::mapの背景情報

マップは連想配列です。つまり、すべてのキーが特定の値にマップされ、キーは一意です。キーが一意ではないマルチマップを実際に作成できるため、これが重要です。

基本的に、キーは一意であるため、キーを配列インデックスとして使用するだけで要素にアクセスしたり、要素を作成したりできます。

例えば:

//Create a map and insert a couple things into it - prices of meat?
std::map<string, float> myMap;
myMap["Chicken"] = 4.99;
myMap["Turkey"] = 6.99;

//Retrieve the price of something using the key.
std::cout << "Chicken costs " << myMap["Chicken"] << std::end;

地図上で標準の挿入操作と位置特定操作を行うこともできますが、連想配列の構文は単純です。なぜわざわざするのでしょうか。:)

PS:念のため、コメントに完全に答えるために、myMap [tokenizedWord] ++の最後にある++は、そのキーに格納されている整数値の値を1インクリメントすることを示しています。myMapも同様に実行できます。 [tokenizedWord] = myMap [tokenizedWord] + 1または、myMap [tokenizedWord] +=1を実行することもできます。

于 2012-08-06T18:48:31.863 に答える
1

問題の完全な実装(ソート用のサンプルコードが必要な場合はお知らせください):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define ARRAY_ELEMS_COUNT(A)    sizeof(A)/sizeof(*A)

typedef struct _word_t
{
        char    *word;
        int     occurr_count;
        struct _word_t  *next;
} word_t;

typedef struct _word_list_t
{
        struct  _word_t *head;
        struct  _word_t *tail;
        int     elems_count;
} word_list_t;

/* Creation of the words list */
word_list_t *make_list(void)
{
        word_list_t *w_list = (word_list_t *)malloc(sizeof (struct _word_list_t));
        if (w_list == NULL)
        {
                fprintf(stderr, "malloc faild --> %s\n", strerror(errno));

                return NULL;
        }
        w_list->head = w_list->tail = NULL;
        w_list->elems_count = 0;

        return w_list;
}

int list_word_lookup(word_list_t *w_list, char *word)
{
        word_t *temp_word = w_list->head;
        while(temp_word)
        {
                if (strcmp(temp_word->word, word) == 0)
                {
                        /* We got it before, increment the count */
                        temp_word->occurr_count++;

                        return 1;
                }
                else
                {
                        temp_word = temp_word->next;
                }
        }

        return 0;
}

/* Adding new words to the list of words if they are not present, otherwise increment their occurrence count */
/* TODO : Sort the list using Merge sort for performance */
int adding_to_list(word_list_t *w_list, char *word)
{
        int     return_status = 0;
        char    *tmp_word = (char *)malloc(sizeof(char)*(strlen(word) + 1));
        word_t  *new_word = (word_t *)malloc(sizeof(struct _word_t));
        /* Empty list */
        if (w_list->head == NULL)
        {
                strcpy(tmp_word, word);
                new_word->word = tmp_word;
                new_word->occurr_count = 1;
                w_list->head = w_list->tail = new_word;
                w_list->head->next = NULL;
                w_list->elems_count++;
        }
        else
        {
                /* The list is not empty */
                /* Checking if the word exist in the list */
                return_status = list_word_lookup(w_list, word);
                if (return_status == 1)
                {
                        fprintf(stdout, "WE got this word before --> increment count\n");
                }
                else
                {
                        strcpy(tmp_word, word);
                        new_word->word = tmp_word;
                        new_word->occurr_count = 1;
                        w_list->tail->next = new_word;
                        w_list->tail = new_word;
                        w_list->tail->next = NULL;
                }
        }

        return 0;
}

void words_list_dump(word_list_t *w_list)
{
        word_t *temp;

        for (temp = w_list->head; temp; temp = temp->next) {
                fprintf(stdout, "Word : %s -- Count = %d\n", temp->word, temp->occurr_count);
        }
}

/* Destroying all words */
void free_words(word_list_t *w_list)
{
        word_t *temp;

        for (temp = w_list->head; temp; temp = temp->next) {
                /* Freeing the word string */
                free(temp->word);
                /* Freeing the word */
                free(temp);
        }
        w_list->head = NULL;
        w_list->tail = NULL;
}

/* Destroying the words list */
void free_words_list(word_list_t *w_list)
{
        if (!w_list)
        {
                return;
        }
        free_words(w_list);
        free(w_list);
}

/* TODO : create a function that converts your input text to a char ** array, so you can pass it to adding_to_list */
/* For testing */
int main(int argc, char **argv)
{
        const char *string[] = {"Hello", "World", "Stackoverflow", "C", "Hello", "C", "WORDS", "words", "List", "list", "Hello", "World", "Count"};
        word_list_t *my_list = make_list();
        int i;

        for (i = 0; i < ARRAY_ELEMS_COUNT(string); i++)
                adding_to_list(my_list, string[i]);
        words_list_dump(my_list);
        free_words_list(my_list);

        return 0;
}
于 2012-08-06T21:00:53.277 に答える
0

strtokこれは、を使用しているが使用していない回答std::mapです。文字列の1回のパスで、入力されたすべての単語が前の単語と照合され、繰り返しがカウントされます。

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

#include <string>
using std::string;

#include <vector>
using std::vector;

#include <cstring>

using std::tolower;

int main()
{
    char *strin;
    string inputstr;
    vector<string> svec;
    vector<int> cvec;
    char *pch;
    int unique_word_count=0;
    while(getline(cin,inputstr))
    {
        //token-ize the string
        //First string
        strin = &inputstr[0];
        pch = std::strtok(strin," ,-");
        bool unique_word_found = true;
        //subsequent words
        while (pch != NULL)
        {
            string word(pch);
            for(string::size_type i=0; i < word.size(); i++)
                word[i]=tolower(word[i]);
            //first word
            //just add to svec and no comparisons
            if(unique_word_count==0)
            {
                svec.push_back(word);
                cvec.push_back(1);
                cvec[unique_word_count++]=1; //init count of first word
                //next word
                pch = std::strtok(NULL, " ,-");
                unique_word_found = true; //reset flag
                continue;
            }

            //start comparing with other words currently in string vector
            //do not do this if only 1 word present
            vector<string>::iterator iter=svec.begin();
            while(iter < svec.end())
            {
                if(word == *iter)
                {
                    //match found
                    cvec[iter-svec.begin()]++; //increment count of that word
                    unique_word_found = false;
                }
                iter++;
            }
            if(unique_word_found)
            {
                //add to unique word list and increment count
                svec.push_back(word);
                cvec.push_back(1);
                cvec[unique_word_count++]=1;
            }

            //next word
            pch = std::strtok(NULL, " ,-");
            unique_word_found = true; //reset flag
        }
    }

    cout << "Word" << " ---> " << "Occurences" << endl;
    for(vector<string>::size_type i=0; i < svec.size(); i++)
    {
        cout << svec[i] << "  --->  " << cvec[i] << endl;
    }
    return 0;
}
于 2016-08-11T13:44:01.207 に答える
0

一般的な戦略は次のとおりです。

  • 入力をサニタイズします(すべての文字を小文字に変換する、不要な句読点を削除するなど)
  • 入力をウォークスルー
  • 文字列に各文字を追加し、スペースが検出されたときに確定します
  • 文字列をKey-Value構造に追加します。文字列がキーです。これが構造にまだ含まれていない新しいエントリである場合は、値1を設定します。それ以外の場合は、現在の値+ 1に設定します(これまでに遭遇した回数をカウントするため)。
  • 単語ごとに繰り返す
  • Key-Value構造をウォークスルーし、各エントリを印刷します。
于 2016-08-11T14:12:45.650 に答える