程序可以统计出词集中各个单词出现的次数 出现位置所在行的行号c语言,字符串统计(自引用结构): 编写程序根据单词出现频率打印输出本身及次数...

#include

#include

#include

#include

typedef struct WORD

{

char *Word;

size_t Count;

struct WORD *Left;

struct WORD *Right;

} WORD;

#define SUCCESS 0

#define CANNOT_MALLOC_WORDARRAY 1

#define NO_WORDS_ON_INPUT 2

#define NO_MEMORY_FOR_WORDNODE 3

#define NO_MEMORY_FOR_WORD 4

#define NONALPHA "1234567890

\v\f\n\t\r+=-*/\\,.;:'#~?<>|{}[]`!\"¡ê$%^&()"

int ReadInputToTree(WORD **DestTree, size_t *Treecount, FILE

*Input);

int AddToTree(WORD **DestTree, size_t *Treecount, char

*Word);

int WalkTree(WORD **DestArray, WORD *Word);

int CompareCounts(const void *vWord1, const void

*vWord2);

int OutputWords(FILE *Dest, size_t Count, WORD

**WordArray);

void FreeTree(WORD *W);

char *my_dupstr(char *s);

int main(void)

{

int Status =

SUCCESS;

WORD *Words =

NULL;

size_t Treecount =

0;

WORD **WordArray =

NULL;

//Read the words on

stdin into a tree

if (SUCCESS ==

Status)

{

Status = ReadInputToTree(&Words,

&Treecount, stdin);

}

//Sanity check for no

sensible input

if (SUCCESS ==

Status)

{

if (0 == Treecount)

{

Status =

NO_WORDS_ON_INPUT;

}

}

//allocate a

sufficiently large array

if (SUCCESS ==

Status)

{

WordArray = malloc(Treecount

*sizeof(*WordArray));

if (NULL == WordArray)

{

Status =

CANNOT_MALLOC_WORDARRAY;

}

}

//walk the tree into the

array

if (SUCCESS ==

Status)

{

Status = WalkTree(WordArray, Words);

}

//sort the array

if (SUCCESS ==

Status)

{

qsort(WordArray, Treecount, sizeof(*WordArray),

CompareCounts);

}

//walk down the

WordArray outputting the values

if (SUCCESS ==

Status)

{

Status = OutputWords(stdout, Treecount,

WordArray);

}

//free the word

array

if (NULL !=

WordArray)

{

free(WordArray);

WordArray = NULL;

}

//free the tree

memory

if (NULL != Words)

{

FreeTree(Words);

Words = NULL;

}

//error report and

finish

if (SUCCESS !=

Status)

{

fprintf(stderr, "Program failed with code %d\n",

Status);

}

system("pause");

return (SUCCESS ==

Status ? EXIT_SUCCESS:EXIT_FAILURE);

}

void FreeTree(WORD *W)

{

if (NULL != W)

{

if (NULL != W->Word)

{

free(W->Word);

W->Word = NULL;

}

if (NULL != W->Left)

{

FreeTree(W->Left);

W->Left = NULL;

}

if (NULL != W->Right)

{

FreeTree(W->Right);

W->Right = NULL;

}

}

}

int AddToTree(WORD **DestTree, size_t *Treecount, char

*Word)

{

int Status =

SUCCESS;

int CompResult =

0;

//safety check

assert(NULL !=

DestTree);

assert(NULL !=

Treecount);

assert(NULL !=

Word);

if (NULL ==

*DestTree)

{

*DestTree = malloc(sizeof **DestTree);

if (NULL == *DestTree)

{

Status =

NO_MEMORY_FOR_WORDNODE;

}

else

{

(*DestTree)->Left = NULL;

(*DestTree)->Right = NULL;

(*DestTree)->Count = 1;

(*DestTree)->Word = my_dupstr(Word);

if (NULL

== (*DestTree)->Word)

{

Status =

NO_MEMORY_FOR_WORD;

free(*DestTree);

*DestTree = NULL;

}

else

{

++*Treecount;

}

}

}

else

{

CompResult = strcmp(Word,

(*DestTree)->Word);

if (0 < CompResult)

{

Status =

AddToTree(&(*DestTree)->Left,

Treecount, Word);

}

else if (0 > CompResult)

{

Status =

AddToTree(&(*DestTree)->Left,

Treecount, Word);

}

else

{

++(*DestTree)->Count;

}

}

return Status;

}

int ReadInputToTree(WORD **DestTree, size_t *Treecount, FILE

*Input)

{

int Status =

SUCCESS;

char Buf[8192] =

{0};

char *Word = NULL;

//safety check

assert(NULL !=

DestTree);

assert(NULL !=

Treecount);

assert(NULL !=

Input);

printf("Please input

strings(# to quit):\n");

while (NULL !=

fgets(Buf, sizeof(Buf), Input))

{

if (strcmp(Buf, "#\n") == 0)

break;

Word = strtok(Buf, NONALPHA);

while (SUCCESS == Status

&& NULL != Word)

{

Status =

AddToTree(DestTree, Treecount, Word);

if

(SUCCESS == Status)

{

Word = strtok(NULL,

NONALPHA);

}

}

}

return Status;

}

int WalkTree(WORD **DestArray, WORD *Word)

{

int Status =

SUCCESS;

static WORD **Write =

NULL;

//safety check

assert(NULL !=

Word);

//store the starting

poing if this is the first call

if (NULL !=

DestArray)

{

Write = DestArray;

}

//now add this node and

its kids

if (NULL != Word)

{

*Write = Word;

++Write;

if (NULL != Word->Left)

{

Status =

WalkTree(NULL, Word->Left);

}

if (NULL != Word->Right)

{

Status =

WalkTree(NULL, Word->Right);

}

}

return Status;

}

int CompareCounts(const void *vWord1, const void

*vWord2)

{

int Result = 0;

WORD * const *Word1 =

vWord1;

WORD * const *Word2 =

vWord2;

assert(NULL !=

vWord1);

assert(NULL !=

vWord2);

if

((*Word1)->Count <

(*Word2)->Count)

{

Result = 1;

}

else if

((*Word1)->Count >

(*Word2)->Count)

{

Result = -1;

}

else

{

Result = 0;

}

return Result;

}

int OutputWords(FILE *Dest, size_t Count, WORD

**WordArray)

{

int Status =

SUCCESS;

size_t Pos = 0;

//safety check

assert(NULL !=

Dest);

assert(NULL !=

WordArray);

//print a header

fprintf(Dest, "Total

Words: %lu\n", (unsigned long)Count);

//print the words in

descending order

while (SUCCESS == Status

&& Pos <

Count)

{

fprintf(Dest, "%lu %s\n", (unsigned

long)WordArray[Pos]->Count,

WordArray[Pos]->Word);

++Pos;

}

return Status;

}

char *my_dupstr(char *s)

{

char *Result =

NULL;

size_t slen = 0;

//sanity check

assert(NULL != s);

//get string

length

slen = strlen(s);

//allocate enough

storage

Result = malloc(slen +

1);

//populate string

if (NULL !=

Result)

{

memcpy(Result, s, slen);

*(Result + slen) = '\0';

}

return Result;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用KMP算法统计文件中特定单词出现次数行号C语言代码,其中每代码都有注释: ```c #include <stdio.h> #include <string.h> // 计算next数组 void getNext(char *pattern, int *next) { int n = strlen(pattern); for (int i = 1, j = 0; i < n; i++) { while (j > 0 && pattern[i] != pattern[j]) { j = next[j - 1]; } if (pattern[i] == pattern[j]) { j++; } next[i] = j; } } // 统计单词出现次数行号 void countWord(char *filename, char *word) { FILE *fp = fopen(filename, "r"); if (fp == NULL) { printf("Error: cannot open file %s\n", filename); return; } char line[1024]; int lineNum = 0; int wordCount = 0; int n = strlen(word); int next[n]; getNext(word, next); while (fgets(line, sizeof(line), fp) != NULL) { lineNum++; char *p = line; while ((p = strstr(p, word)) != NULL) { int pos = p - line; int i = pos - n; if (i >= 0 && line[i] != ' ' && line[i] != '\t') { // 如果单词出现在一个单词的中间,忽略 p++; continue; } i = pos + strlen(word); if (i < strlen(line) && line[i] != ' ' && line[i] != '\t' && line[i] != '\n' && line[i] != '\r') { // 如果单词出现在一个单词的中间,忽略 p++; continue; } wordCount++; printf("Line %d: %s", lineNum, line); p += n; } } printf("Word '%s' appears %d times in file %s\n", word, wordCount, filename); fclose(fp); } int main() { char filename[256]; char word[256]; printf("Enter filename: "); scanf("%s", filename); printf("Enter word to search: "); scanf("%s", word); countWord(filename, word); return 0; } ``` 使用方法:编译运上述代码后,依次输入要查找的文件名和单词即可。例如,输入`test.txt`和`hello`,程序会输出该文件中单词`hello`出现次数行号
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值