- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我根据改进的 Lansky 算法实现了简单的音节化算法,但是当我需要在超过 200 万个单词的语料库上运行这个算法时,它真的很慢。有人可以指出导致它如此缓慢的原因吗?算法如下:
最后一个元音(元音组)之后的所有内容都属于最后一个音节
第一个元音(元音组)之前的所有内容都属于第一个音节
如果元音之间的辅音个数为偶数(2n),则分为halves 前半部分属于左元音,第二部分属于右元音 (n/n)。
如果元音之间的辅音个数是奇数(2n + 1),我们将它们分成n/n + 1 个部分。
如果元音之间只有一个辅音,则属于左元音。
#include <stdio.h>
#include <string.h>
#define VOWELS "aeiou"
int get_n_consonant_between(char *word, int length) {
int count = 0;
int i = 0;
while (i++ < length) {
if (strchr(VOWELS, *word)) break;
word++;
count++;
}
return count;
}
void syllabification(char *word, int n_vowel_groups) {
int i = 0, length = strlen(word), consonants;
int syllables = 0, vowel_group = 0, syl_length = 0;
char *syllable = word;
char hola[length];
memset(hola, 0, length);
if (n_vowel_groups < 2) {
printf("CAN'T BE SPLIT INTO SYLLABLES\n\n");
return;
}
while (i < length) {
if (strchr(VOWELS, word[i])) {
syl_length++;
i++;
if (vowel_group) continue;
vowel_group = 1;
}
else {
if (vowel_group) {
consonants = get_n_consonant_between(word + i, length - i);
if (consonants == 1) {
// printf("only one consonant\n");
syl_length++;
strncpy(hola, syllable, syl_length);
i++;
}
else {
int count = consonants / 2;
if ((consonants % 2) == 0) { /* number of consonants is 2n, first half belongs to the left vowel */
syl_length += count;
}
else {
syl_length += count;
}
strncpy(hola, syllable, syl_length);
i += count;
}
syllables++;
if (syllables == n_vowel_groups) {
printf("syllable done %d: %s\n", syllables, syllable);
break;
}
printf("syllable %d: %s\n", syllables, hola);
syllable = word + i;
syl_length = 0;
memset(hola, 0, length);
}
else {
syl_length++;
i++;
}
vowel_group = 0;
}
}
}
int count_vowel_groups(char *word) {
int i, nvowels = 0;
int vowel_group = 0;
for (i = 0; i < strlen(word); i++) {
if (strchr(VOWELS, word[i])) {
if (vowel_group) continue;
vowel_group = 1;
}
else {
if (vowel_group) nvowels++;
vowel_group = 0;
}
}
// printf("%d vowel groups\n", nvowels);
return nvowels;
}
void repl() {
char *line = NULL;
size_t len = 0;
int i = 0;
int count;
FILE *file = fopen("../syllables.txt", "r");
while(i++ < 15) {
getline(&line, &len, file);
printf("\n\n%s\n", line);
count = count_vowel_groups(line);
syllabification(line, count);
}
}
int main(int argc, char *argv[]) {
// printf("Syllabification test:\n");
repl();
}
`
最佳答案
要检查实现是否正确,需要执行大量代码正确,主要是因为我不知道术语(比如什么是 a算法的元音组)。我查了一下,谷歌给我返回了很多用于音节化的研究论文(我只能看到摘要)不同的语言,所以我不确定代码是否正确。
但我有一些建议可能会使您的代码更快:
将所有strlen(word)
移出for
循环条件。保存长度在变量中并改用该变量。所以从
for (i = 0; i < strlen(word); i++)
到
size_t len = strlen(word);
for(i = 0; i < len; i++)
不要使用 strchr
检查字符是否为元音。我会使用查找这个表:
// as global variable
char vowels[256];
int main(void)
{
vowels['a'] = 1;
vowels['e'] = 1;
vowels['i'] = 1;
vowels['o'] = 1;
vowels['u'] = 1;
...
}
当你想检查一个字符是否是元音时:
// 0x20 | c make c a lower case character
if(vowel[0x20 | word[i]])
syl_length++;
i++;
if (vowel_group) continue;
vowel_group = 1;
}
第一个建议可能会给你一个小的性能提升,编译器是非常聪明,无论如何都可以优化它。第二个建议可能会给你更多的表现,因为它只是一个查找。在最坏的情况下strchr
必须多次遍历整个 "aeiou"
数组。1
注释
1我做了一个非常粗糙的程序来比较建议。我添加了一些额外的代码,希望编译器不会积极优化功能。
#include <stdio.h>
#include <string.h>
#include <time.h>
int test1(time_t t)
{
char text[] = "The lazy dog is very lazy";
for(size_t i = 0; i < strlen(text); ++i)
t += text[i];
return t;
}
int test2(time_t t)
{
char text[] = "The lazy dog is very lazy";
size_t len = strlen(text);
for(size_t i = 0; i < len; ++i)
t += text[i];
return t;
}
#define VOWELS "aeiou"
char vowels[256];
int test3(time_t t)
{
char text[] = "The lazy dog is very lazy";
size_t len = strlen(text);
for(size_t i = 0; i < len; ++i)
{
if (strchr(VOWELS, text[i]))
t += text[i];
t += text[i];
}
return t;
}
int test4(time_t t)
{
char text[] = "The lazy dog is very lazy";
size_t len = strlen(text);
for(size_t i = 0; i < len; ++i)
{
if(vowels[0x20 | text[i]])
t += text[i];
t += text[i];
}
return t;
}
int main(void)
{
vowels['a'] = 1;
vowels['e'] = 1;
vowels['i'] = 1;
vowels['o'] = 1;
vowels['u'] = 1;
long times = 50000000;
long tmp = 0;
clock_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
for(long i = 0; i < times; ++i)
{
clock_t start,end;
time_t t = time(NULL);
start = clock();
tmp += test1(t);
end = clock();
t1 += end - start;
//t1 += ((double) (end - start)) / CLOCKS_PER_SEC;
start = clock();
tmp += test2(t);
end = clock();
t2 += end - start;
start = clock();
tmp += test3(t);
end = clock();
t3 += end - start;
start = clock();
tmp += test4(t);
end = clock();
t4 += end - start;
}
printf("t1: %lf %s\n", ((double) t1) / CLOCKS_PER_SEC, t1 < t2 ? "wins":"loses");
printf("t2: %lf %s\n", ((double) t2) / CLOCKS_PER_SEC, t2 < t1 ? "wins":"loses");
printf("t3: %lf %s\n", ((double) t3) / CLOCKS_PER_SEC, t3 < t4 ? "wins":"loses");
printf("t4: %lf %s\n", ((double) t4) / CLOCKS_PER_SEC, t4 < t3 ? "wins":"loses");
printf("tmp: %ld\n", tmp);
return 0;
}
结果是:
$ gcc b.c -ob -Wall -O0
$ ./b
t1: 10.866770 loses
t2: 7.588057 wins
t3: 10.801546 loses
t4: 8.366050 wins
$ gcc b.c -ob -Wall -O1
$ ./b
t1: 7.409297 loses
t2: 7.082418 wins
t3: 11.415080 loses
t4: 7.847086 wins
$ gcc b.c -ob -Wall -O2
$ ./b
t1: 6.292438 loses
t2: 5.855348 wins
t3: 9.306874 loses
t4: 6.584076 wins
$ gcc b.c -ob -Wall -O3
$ ./b
t1: 6.317390 loses
t2: 5.922087 wins
t3: 9.436450 loses
t4: 6.722685 wins
关于c - 实现音节化算法但真的很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49090878/
我是 python 的新手。我试图找到我的文本的频率分布。这是代码, import nltk nltk.download() import os os.getcwd() text_file=open(
我对安卓 fragment 感到困惑。我知道内存 fragment 但无法理解什么是 android fragment 问题。虽然我发现很多定义,比如 Android fragmentation re
尝试对 WordPress 进行 dockerise 我发现了这个场景: 2个数据卷容器,一个用于数据库(bbdd),另一个用于wordpress文件(wordpress): sudo docker
这个问题已经有答案了: From the server is there a way to know that my page is being loaded in an Iframe (1 个回答)
我正在玩小型服务器,试图对运行在其上的服务进行docker化。为简化起见,假设我必须主要处理:Wordpress和另一项服务。 在Docker集线器上有许多用于Wordpress的图像,但是它们似乎都
我想要发生的是,当帐户成功创建后,提交的表单应该消失,并且应该出现一条消息(取决于注册的状态)。 如果成功,他们应该会看到一个简单的“谢谢。请检查您的电子邮件。” 如果不是,那么他们应该会看到一条适当
就是这样,我需要为客户添加一个唯一标识符。通过 strip 元数据。这就是我现在完全构建它的方式,但是我只有最后一部分告诉我用户购买了哪个包。 我试着看这里: Plans to stripe 代码在这
我有一个类将执行一些复杂的操作,涉及像这样的一些计算: public class ComplexAction { public void someAction(String parameter
这个问题已经有答案了: maven add a local classes directory to module's classpath (1 个回答) 已关闭10 年前。 我有一些不应更改的旧 E
我使用 fragment 已经有一段时间了,但我经常遇到一个让我烦恼的问题。 fragment 有时会相互吸引。现在,我设法为此隔离了一个用例,它是这样的: Add fragment A(也使用 ad
我的 html 中有一个 ol 列表,上面有行条纹。看起来行条纹是从数字后面开始的。有没有办法让行条纹从数字开始? 我已经包含了正在发生的事情的片段 h4:nth-child(even) {
如何仅使用 css 将附加图像 html 化? 如果用纯 css 做不到,那我怎么能至少用一个图像来做 最佳答案 这不是真正的问题,而是您希望我们为您编写代码。我建议您搜索“css breadcrum
以下是 Joshua 的 Effective Java 的摘录: If you do synchronize your class internally, you can use various te
在这里工作时,我们有一个框向业务合作伙伴提供 XML 提要。对我们的提要的请求是通过指定查询字符串参数和值来定制的。其中一些参数是必需的,但很多不是。 例如,我们要求所有请求都指定一个 GUID 来标
我有 3 个缓冲区,其中包含在 32 位处理器上运行的 R、G、B 位数据。 我需要按以下方式组合三个字节: R[0] = 0b r1r2r3r4r5r6r7r8 G[0] = 0b g1g2g3g4
我最近发现了关于如何使用 History.js、jQuery 和 ScrollTo 通过 HTML5 History API 对网站进行 Ajax 化的要点:https://github.com/br
我们有一个 Spring Boot 应用程序,由于集成需要,它变得越来越复杂——比如在你这样做之后发送一封电子邮件,或者在你之后广播一条 jms 消息等等。在寻找一些更高级别的抽象时,我遇到了 apa
我正在尝试首次实施Google Pay。我面临如何指定gateway和gatewayMarchantId的挑战。 我所拥有的是google console帐户,不知道在哪里可以找到此信息。 priva
昨天下午 3 点左右,我为两个想要从一个 Azure 帐户转移到另一个帐户的网站设置了 awverify 记录。到当天结束时,Azure 仍然不允许我添加域,所以我赌了一把,将域和 www 子域重新指
我正在使用terms facet在elasticsearch服务器中获取顶级terms。现在,我的标签"indian-government"不被视为一个标签。将其视为"indian" "governm
我是一名优秀的程序员,十分优秀!