上篇《回文》在结尾部分遗留关于语句倒置问题,例如:I am a student => student a am I
今天就来说说这个功能的实现思路。
既然在回文中提到这个扩展,那么使用回文的实现思路来做这个事情应该是可行的,
再不济,使用调换对应位的字符方式能将所有的字符调转过来,但是显然这样的结果一般是无法接受的。
比如:I am a student => tneduts a ma I
这个离 student a am I 这样的结果好像很近了,但是仿佛又好远。
在完全倒置的基础上,就差一个对单词本身的调转,即:tneduts => student
已经完全调换过一次,再倒置一次单词就回来了,有点负负得正的感觉。
总结一下吧,文采有点烂,没办法,语文是英语老师代课的(又黑老师了~)
全局倒置所有字符,后将单词倒置,或者反过来,先导致单词,后全局倒置(自己有点晕~)
以前者为例:
倒置全局字符:
void swap_char(char *p,char *q){ char tmp; while(p < q){ tmp = *p; *p = *q; *q = tmp; p++,q--; } } void reserver_string(char *string_value){ char *p,*q; p = string_value; q = string_value + strlen(string_value) - 1; swap_char(p,q); }
在已经倒置全局字符的基础上倒置每个词,即修改后得:
void reserver_string(char *string_value){ char *p,*q,*r; p = string_value; r = q = string_value + strlen(string_value) - 1; swap_char(p,q); p = string_value; while((*p < 'A' || *p >'Z') && (*p < 'a' || *p > 'z')) p++; q = p; while(p < r){ while((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <='Z')) q++; swap_char(p,q-1); while((*q < 'A' || *q >'Z') && (*q < 'a' || *q > 'z')) q++; p = q; } }
主调函数:
#include <stdio.h> #include <string.h> #define N 80 int read_file(char *file_name){ char str[N]="\0"; FILE *fp; fp = fopen(file_name,"r"); while(fgets(str,N,fp)){ reserver_string(str); fprintf(stdout,str); } fclose(fp); return 0; } int main(void){ char file_path[10]="tmp.txt"; //fprintf(stdout,"Enter a file name:"); //scanf("%s",file_path); read_file(file_path); printf("\n"); return 0; }
测试结果:
user@host:~/shell_task$ cat tmp.txt
I am soildor,you can not cheat your country.
user@host:~/shell_task$ ./Unsort
.country your cheat not can you,soildor am I
到此基本实现预期目标,但是实现这个功能的目的是什么呢?
在回答这个问题前,容我给各位先卖个关子。
同样留个问题:如何计算一篇文中某些关键词的频率呢?