【发布时间】:2020-07-23 16:40:21
【问题描述】:
我一直在使用一些旧代码,并且遇到了我不久前创建的一个函数,它计算每个字母在给定字符串中出现的次数。在我的初始函数中,我将遍历字符串 26 次,计算每个字母在循环中出现的次数。但是,我知道这确实效率低下,所以我尝试这样做:
int *frequency_table(char *string) {
int i;
char c;
int *freqCount = NULL;
freqCount = mallocPtr(freqCount, 26, sizeof(int), "freqCount"); /* mallocs and checks for out of memory */
for (i = 0; string[i] != '\0'; i++) {
c = string[i];
if (isalpha(c)) {
isupper(c) ? freqCount[c - 65]++ : freqCount[c - 97]++;
}
}
return (freqCount);
}
上面的代码循环遍历一个字符串并检查每个字符。如果字符是字母(az 或 AZ),那么我会在 freqCount 数组中的特定索引处增加频率计数(其中索引 0 = a\A, 1 = b\B, ... , 25 = Z Z)。
代码似乎计算得很好,但是当我打印数组时,我得到以下输出:
字符串:“abcdefghijklmnopqrstuvwxyziii”
a/A -1276558703
b/B 32754
c/C -1276558703
d/D 32754
e/E 862570673
f/F 21987
g/G 862570673
h/H 21987
i/I 4
j/J 1
k/K 1
l/L 1
m/M 1
n/N 1
o/O 1
p/P 1
q/Q 1
r/R 1
s/S 1
t/T 1
u/U 1
v/V 1
w/W 1
x/X 1
y/Y 1
z/Z 1
作为参考,我按以下方式打印数组:
for (i = 0; i < 26; i++) {
printf("%c/%c %d\n", i + 97, i + 65, freqCount[i]);
}
我检查以确保指针分配正确,我确定我没有覆盖这个内存位置。也许我遗漏了一些东西,但我真的不明白为什么它会从 a\A-h\H 打印垃圾内存值。
另外,如果有更有效的方法来做我想做的事,我很想听听。
谢谢
【问题讨论】:
-
您从未将数组的值设置为 0,因此您
++处理了一些留在内存中的垃圾。 -
malloc不会初始化数组,因此代码需要使用memset或循环来初始化它,或者使用calloc而不是malloc -
顺便说一句,65 和 97 应该分别写为
'A'和'a'。这使代码更易于阅读,您不必记住这些数字是什么。 -
@Timothy Catana 顺便说一句,并非所有字母都没有间隙地相互跟随。例如,对于 EBCDIC 编码,该程序将无法运行。
-
memset(freqCount, 0, 26*sizeof(int))... 或者只是calloc()而不是malloc()... 或者根本不使用动态分配,因为它只是一个 26int数组:int freqCount[26] = {0};.