求算法,统计多少个单词

heise007w 2009-08-17 09:05:46
给定一字符串如:
this is a stringss,   I# will find how many words $$and “the longests and shortest” words in this string...a
要求输出,单词数量20,最长单词stringss,longests,shortest,最短单词a,I,a,标点不计入单词
我写了一个用std::string的find_first_of26字母和find_first_not_of26字母确定单词首尾,用vector<string>存最长最短单词,如果长度相同则push_back,长度更长则先clear后push_back。感觉效率低,求更高效的算法
...全文
284 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhusizhi007 2009-08-17
  • 打赏
  • 举报
回复
个人觉的用vector<set>或者vector<multiset>格式更好,但是不知道楼主题意,如果两个单词重复是不是算一个,算一个则用vector<set>,算两个则用vector<multiset>,vector的下标就是单词的长度,所以处理结束后在vector<multiset> 结构中的第一个中的multiset中是所有长为1的单词,vector<multiset> 结构中的第二个multiset中的集中是所有长为2的单词,依此力推
heise007w 2009-08-17
  • 打赏
  • 举报
回复
4L的你好,如果是大文本,而且单词是按长度排序的话,那不是所有的单词都要存进vector了?空间消耗就大了
heise007w 2009-08-17
  • 打赏
  • 举报
回复
primer里面没有要求统计单词长度,所以逗号它也放入计算了,我想统计单词长度所以用了find_first_of来去掉标点。
4L的说的好。。
我在想查找方面还可以更加优化吗?
KWHOK 2009-08-17
  • 打赏
  • 举报
回复
lz这个问题其实是空间的衡量问题,

但是无论怎么操作,都是O(n)的,因为每个单词最多进出vector各一次

如果文本比较大,预计相同长度的单词数目很多,
则不妨扫描二次文本, 第一次,确定最长长度,第二次,获取该长度的单词

当然如果文本比较小的话,都无所谓了!
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20090629/22/5756dd2f-6a2a-4ba8-acb7-d014efd9acb5.html

这个是C++ primer 里的TextQuery。


/* text_query.h*/

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <string>

using namespace std;

class TextQuery
{
public:
typedef vector< string >::size_type line_no;
typedef map< string,set<line_no> >::iterator map_word_iterator;
void read_file(ifstream &is)
{
store_file(is);
build_map();
}
set< line_no > run_query(const string &) const;
string text_line(line_no) const;
private:
void store_file(ifstream &);
void build_map();
vector< string > lines_of_text;
map< string,set< line_no > > word_map;
};


/*test_query.cpp*/

#pragma warning(disable:4786)
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <set>
#include <string>

#include "textQuery.h"

using namespace std;

void TextQuery::store_file(ifstream &is)
{
string textline;
while (getline(is, textline))
lines_of_text.push_back(textline);
}

void TextQuery::build_map()
{
for(line_no line_num = 0; line_num != lines_of_text.size(); ++line_num)
{
istringstream line(lines_of_text[line_num]);
string word;
while (line >>word)
word_map[word].insert(line_num);
}
}

set< TextQuery::line_no > TextQuery::run_query(const string &query_word) const
{
map< string, set< line_no > >::const_iterator loc = word_map.find(query_word);
if (loc == word_map.end())
return set<line_no>();
else
return loc->second;
}

string TextQuery::text_line(line_no line) const
{
if (line <lines_of_text.size())
return lines_of_text[line];
throw out_of_range("line number out of ranger");
}


/*main.cpp*/

#pragma warning(disable:4786)
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <set>
#include <string>

#include "textQuery.h"

using namespace std;

typedef set<TextQuery::line_no> line_nums;

void print_results(const set<TextQuery::line_no> &locs, const string &sought, const TextQuery &file);

ifstream& open_file(ifstream &in, const string &file);

int main()
{
ifstream infile;
if ( !open_file(infile, "text_in.txt") )
{
cerr << "No input file!" << endl;
return EXIT_FAILURE;
}
TextQuery tq;
tq.read_file(infile);
while (true)
{
cout << "enter word to look for,or q for qiut: ";
string s;
cin >> s;
if(!cin || s == "q")
break;
set<TextQuery::line_no> locs =tq.run_query(s);
print_results(locs, s, tq);
}
return 0;
}

void print_results(const set<TextQuery::line_no> &locs, const string &sought, const TextQuery &file)
{
line_nums::size_type size = locs.size();
cout << "\n" <<sought << " occurs " << size << " " <</*make_plural(size, "time" , "s") <<*/endl;
line_nums::const_iterator it = locs.begin();
for( ; it != locs.end(); ++it)
{
cout <<"\t(line " << (*it) +1 << ")" <<file.text_line(*it) <<endl;
}

}


ifstream& open_file(ifstream &in, const string &file)
{
in.close();
in.clear();
in.open(file.c_str());
return in;
}





abcdef0966 2009-08-17
  • 打赏
  • 举报
回复
xingzhe2001 2009-08-17
  • 打赏
  • 举报
回复
[Quote=引用楼主 heise007w 的回复:]
如果长度相同则push_back,长度更长则先clear后push_back。感觉效率低,求更高效的算法
[/Quote]

你用clear,你用个int n记录当前最长的单词的个数,发现新的单词比以前的长,个数就置为1,发现新的单词和以前一样长,个数就++,最后你的vector的后n个单词就是你要找的单词,直接读并输出就好了。

感觉你把vector当成stack用了。
lijian22500 2009-08-17
  • 打赏
  • 举报
回复
C语言操作,容器是为提供给你方便的,要是对具体应用 还可能得你自己设计算法。而不去调用别人的函数,类。
heise007w 2009-08-17
  • 打赏
  • 举报
回复
长度一样都要保存啊,一个变量不够吧。
asksgp 2009-08-17
  • 打赏
  • 举报
回复
没必要用vector,直接用两个变量保存最长和最短的。每次读一个单词就和这2变量比较。
灌水九段 2009-08-17
  • 打赏
  • 举报
回复
没必要用到容器吧 就设一个min 一个max 每个变量比较2次 还省空间
min<x?min=x;min;
max<x?max=x;max;
wwfeng0601 2009-08-17
  • 打赏
  • 举报
回复
也可以定义数组存放单词。
HengStar 2009-08-17
  • 打赏
  • 举报
回复
如果允许的话建议用boost的正则表达式
zdeepblue 2009-08-17
  • 打赏
  • 举报
回复
可以用std的set
cnhome 2009-08-17
  • 打赏
  • 举报
回复
boost::regex 正则表达式

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧