我写的几百行程序,统计文件中各单词出现的个数,希望大师能对算法跟代码点评一下!

kevin820601 2009-06-06 03:14:13
word.h
#ifndef _WORD_H
#define _WORD_H

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

#ifdef __cplusplus
extern "C"
{
#endif

typedef enum tagRET_CODE_E
{
SUCCESS,
FAILURE,
PARA_ERR,
MEM_ERR,
}RET_CODE_E;

#define NHASH 29989
#define MULT 31

#define TRUE 1
#define FALSE 0

typedef void VOID;
typedef char CHAR;
typedef unsigned long ULONG;


typedef struct tagWORD_NODE_S
{
CHAR *pcWord;
ULONG ulCnt;
struct tagWORD_NODE_S* pstNext;
}WORD_NODE_S;

#define WORD_ARE_EQUAL(pstr1, pstr2) (!strcmp(pstr1, pstr2) ? TRUE:FALSE)
#define WORD_SHOWINFO(str) printf("%s", str)

VOID Word_ShowStatistics();
ULONG Word_GenHashIndex(CHAR* pcWordString, ULONG* pulHashIdx);
VOID Word_UpdateHashTable(CHAR* pcWord);
WORD_NODE_S* Word_SearchIdenticalNode(WORD_NODE_S* pstStartNode, CHAR* pcWord);
VOID Word_DeInit();

#ifdef __cplusplus
}
#endif
#endif
...全文
196 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
光宇广贞 2009-06-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 hairetz 的回复:]
引用 9 楼 kevin820601 的回复:
大哥,你难道不知道hash的效率比树还要高吗


引用 8 楼 hairetz 的回复:
vector < string > lines_of_text;
map < string,set < line_no > > word_map;


这2个是预处理啊,
查找的时候效率就是map的效率啊,红黑树的效率,有什么行不行的啊。



我知道啊。
但是你不知道hash的冲突是不可能根治的吗?
来多点数据,你的效率还不一样降低。

何况stl直接可以用的…
[/Quote]

大牛开一个教学贴,公布一下你的所有做过的HASH算法吧,顺便散10000分,我第一个回,然后咱就结贴得了。
GoonYangXiaofang 2009-06-06
  • 打赏
  • 举报
回复
代码风格不错,赞!

Word_UpdateHashTable函数里的return语句太多了。
pathuang68 2009-06-06
  • 打赏
  • 举报
回复
写得还是不错。
pysjp 2009-06-06
  • 打赏
  • 举报
回复
程序处理的不错
有以下建议供拍砖:
在.h文件中只需提供以下三个接口供用户调用
Word_UpdateHashTable
Word_ShowStatistics();
Word_DeInit();

其它的接口和数据结构建议声明道.c文件中,不要暴露更多的接口给用户,尤其是数据部分。
blh 2009-06-06
  • 打赏
  • 举报
回复
对于这类问题,用lex语言更好,呵呵
kevin820601 2009-06-06
  • 打赏
  • 举报
回复
眼力很不错的啊,呵呵

[Quote=引用 15 楼 goodname 的回复:]
粗粗看了一遍,程序看起来写的很不错,有一定的水平。

程序退出的时候,使用 Word_DeInit();
清理资源,但是没有释放pcWord,这是一处错误。
[/Quote]
goodname 2009-06-06
  • 打赏
  • 举报
回复
粗粗看了一遍,程序看起来写的很不错,有一定的水平。

程序退出的时候,使用 Word_DeInit();
清理资源,但是没有释放pcWord,这是一处错误。
勤奋的沉沦 2009-06-06
  • 打赏
  • 举报
回复
好好的void 为什么要搞成VOID
char 为什么要弄成CHAR?
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 kevin820601 的回复:]
大哥,你难道不知道hash的效率比树还要高吗


引用 8 楼 hairetz 的回复:
vector < string > lines_of_text;
map < string,set < line_no > > word_map;


这2个是预处理啊,
查找的时候效率就是map的效率啊,红黑树的效率,有什么行不行的啊。
[/Quote]

我知道啊。
但是你不知道hash的冲突是不可能根治的吗?
来多点数据,你的效率还不一样降低。

何况stl直接可以用的。

hash我做过不少,那是因为是特殊环境,不能数据库,不能用stl。
MichaelBomb 2009-06-06
  • 打赏
  • 举报
回复
学习 观望
kevin820601 2009-06-06
  • 打赏
  • 举报
回复
老弟,C语言可了没有map这玩意啊

[Quote=引用 10 楼 huizhouxueyuan 的回复:]
让我处理的话,我会用 map 来处理,标准库的东西为啥不用呢? 还有~ 程序一点注释都没有~ 第一感觉就是不想看!
[/Quote]
huizhouxueyuan 2009-06-06
  • 打赏
  • 举报
回复
让我处理的话,我会用 map 来处理,标准库的东西为啥不用呢? 还有~ 程序一点注释都没有~ 第一感觉就是不想看!
kevin820601 2009-06-06
  • 打赏
  • 举报
回复
大哥,你难道不知道hash的效率比树还要高吗

[Quote=引用 8 楼 hairetz 的回复:]
vector < string > lines_of_text;
map < string,set < line_no > > word_map;


这2个是预处理啊,
查找的时候效率就是map的效率啊,红黑树的效率,有什么行不行的啊。
[/Quote]
  • 打赏
  • 举报
回复
vector< string > lines_of_text;
map< string,set< line_no > > word_map;


这2个是预处理啊,
查找的时候效率就是map的效率啊,红黑树的效率,有什么行不行的啊。
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 kevin820601 的回复:]
楼上的效率应该不行吧
[/Quote]

呵呵,那是因为该代码的功能,不只统计该单词的系数,还要显示该单词出现在什么地方。
kevin820601 2009-06-06
  • 打赏
  • 举报
回复
楼上的效率应该不行吧
十八道胡同 2009-06-06
  • 打赏
  • 举报
回复
额,hairetz

  • 打赏
  • 举报
回复
冒昧的贴上C++ primer的例子给你看下。


/*TextQuery.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;
};

/*TestQuery.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;
}

kevin820601 2009-06-06
  • 打赏
  • 举报
回复
main.c
#include <stdio.h>
#include "word.h"
#include<string.h>

int main()
{
CHAR acWord[20] = {0};

FILE* fin=fopen("f:\\test.txt","r");

if (fin==NULL)
{
printf("Open files error\n");
return 0;
}

while (!feof(fin))
{
fscanf(fin,"%s",acWord);
if (strlen(acWord)==1 && acWord[0]==' ')
{
continue;
}
else
{
Word_UpdateHashTable((CHAR*)acWord);
}

}
fclose(fin);

Word_ShowStatistics();

Word_DeInit();
}
kevin820601 2009-06-06
  • 打赏
  • 举报
回复
/* word.c */
#include "word.h"

WORD_NODE_S gstWordNodePtrArray[NHASH] = {0};

ULONG Word_Gen_HashIndex(CHAR* pcWordString, ULONG* pulHashIdx)
{
CHAR *pcTmp = NULL;
ULONG ulHashSum = 0;

if ((NULL == pcWordString) || (NULL == pulHashIdx))
{
return PARA_ERR;
}

pcTmp = pcWordString;
while ('\0' != *pcTmp)
{
ulHashSum = ulHashSum * MULT + *pcTmp;
pcTmp++;
}

*pulHashIdx = ulHashSum % NHASH;

return SUCCESS;
}

VOID Word_UpdateHashTable(CHAR* pcWord)
{
ULONG ulHashIdx = 0;
ULONG ulRetVal = 0;
WORD_NODE_S *pstWordNode = NULL;

if (NULL == pcWord)
{
return;
}

ulRetVal = Word_Gen_HashIndex(pcWord, &ulHashIdx);
if (SUCCESS != ulRetVal)
{
return;
}

pstWordNode = Word_SearchIdenticalNode(gstWordNodePtrArray[ulHashIdx].pstNext,
pcWord);
if (NULL != pstWordNode)
{
pstWordNode->ulCnt++;
return;
}

pstWordNode = (WORD_NODE_S*)malloc(sizeof(WORD_NODE_S));
if (NULL == pstWordNode)
{
WORD_SHOWINFO("Error: memory shortage.");
return;
}

pstWordNode->pcWord = (CHAR*)malloc(strlen(pcWord) + 1);
if(NULL == pstWordNode->pcWord)
{
WORD_SHOWINFO("Error: memory shortage.");
free(pstWordNode);
return;
}

strcpy(pstWordNode->pcWord, pcWord);
pstWordNode->ulCnt = 1;

pstWordNode->pstNext = gstWordNodePtrArray[ulHashIdx].pstNext;
gstWordNodePtrArray[ulHashIdx].pstNext = pstWordNode;

return;
}

WORD_NODE_S* Word_SearchIdenticalNode(WORD_NODE_S* pstStartNode,
CHAR* pcWord)
{
WORD_NODE_S* pstTmpNode = NULL;

if ((NULL == pstStartNode) || (NULL == pcWord))
{
return NULL;
}

pstTmpNode = pstStartNode;

while (NULL != pstTmpNode)
{
if (TRUE == WORD_ARE_EQUAL((CHAR*)pstTmpNode->pcWord, pcWord))
{
break;
}

pstTmpNode = pstTmpNode->pstNext;
}

return pstTmpNode;
}

VOID Word_ShowStatistics()
{
ULONG ulLoopCnt = 0;
WORD_NODE_S *pstTmpNode = NULL;

for (ulLoopCnt = 0; ulLoopCnt < NHASH; ulLoopCnt++)
{
if (NULL == gstWordNodePtrArray[ulLoopCnt].pstNext)
{
continue;
}

pstTmpNode = gstWordNodePtrArray[ulLoopCnt].pstNext;

while(NULL != pstTmpNode)
{
printf("%20s: %10d\n", pstTmpNode->pcWord, pstTmpNode->ulCnt);
pstTmpNode = pstTmpNode->pstNext;
}
}
}

VOID Word_DeInit()
{
ULONG ulLoopCnt = 0;
WORD_NODE_S *pstCurNode = NULL;
WORD_NODE_S *pstNextNode = NULL;

for (ulLoopCnt = 0; ulLoopCnt < NHASH; ulLoopCnt++)
{
pstCurNode = gstWordNodePtrArray[ulLoopCnt].pstNext;
while (NULL != pstCurNode)
{
pstNextNode = pstCurNode->pstNext;
free(pstCurNode);
pstCurNode = pstNextNode;
}
}

return;
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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