C++,计算字符串中的重复单词并显示
C++, count repeated words in the string and display
我有字符串说"走路说话,不能不会不会说话"。我想数一数被重新涂抹的单词并显示。注意:它不区分大小写。
我用过分量仪
strtok(string, ",.;:"!? -_nt*()@#=+");
并将其保存在
char *temp[100];
现在如何检查单词的重复?并显示如下
3 won't
2 talk
1 can't
1 walk
它应从最高重复到最低重复显示。如果重复相同,则显示字母顺序。
对不起,我的英语不好。
使用 std::string 来保存strtok()
的结果。 然后创建一个std::map<string, int>
来保存字符串(键)发生的次数。
您可以使用以下内容填充地图:
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
。 不幸的是,映射是关联容器,您无法对它们进行排序,因为它会破坏它们的内部排序。
标准::地图的背景信息
映射是一个关联数组,这意味着每个键都映射到一个特定的值,并且键是唯一的。 您实际上可以创建一个键不唯一的多重映射,因此这很重要。
基本上,由于键是唯一的,因此您只需将键用作数组索引即可访问或创建元素。
例如:
//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。
问题的完整实现(如果您需要排序的示例代码,请告诉我):
#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 --> %sn", 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 countn");
}
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 = %dn", 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;
}
这是一个使用 strtok
但没有std::map
的答案。在一次字符串传递中,将检查中的每个单词与以前的单词并计算重复次数。
#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;
}
一般策略可以如下:
- 清理输入(将所有字符转换为小写,删除不需要的标点符号等)
- 演练输入
- 将每个字符添加到字符串中,在遇到空格时完成
- 将字符串添加到键值结构。字符串是键。如果这是结构中尚未包含的新条目,请将值设置为 1。否则设置为当前值+1(以便计算到目前为止遇到的次数)。
- 对每个单词重复此操作
- 演练键值结构并打印每个条目。
- 以C++显示单词的所有前缀
- 显示文件中具有最小给定元音数的单词
- C++ 随机生成的字典单词将仅显示以 B 开头的单词
- 使用 c++ MuPDF 突出显示 PDF 中的一些单词
- 如何在C++中突出显示整个单词?
- 尝试创建一个读取.txt文件,显示它,计数唯一单词的程序,并在使用了多少次的情况下显示独特的单词.C
- 对于文件中的每个不同单词,显示该单词在文件中出现的次数
- 我如何修改我的C 程序以显示用户输入的单词,并使用堆栈向后
- 在C/C 中显示来自TXT文件的单词
- 如何检查文本文件中每个单词的出现次数并显示C++次数
- Check Writer:使程序将值10-19显示为单词
- C++,计算字符串中的重复单词并显示
- 有没有一个网站可以生成所有可能的显示单词的方式
- 当键入指定单词作为第一个字母时显示输出,并忽略后面的其他单词
- 突出显示qtextedit中x和y作为位置的单词
- 在c++中显示一行vs单词
- 如何使用c++在没有读线的情况下显示字符串中的多个单词
- 从文本文件中查找一个单词,然后使用c++显示该单词所在的行号
- 我如何写一个Qt正则表达式来突出显示字符串开始和结束与非单词字符
- visual studio 2010 - c++显示有组织的单词列表