这应该是一个简单的函数(它计算字符串中唯一字符的数量),但我遇到了一个奇怪的问题。请注意,我的代码使用只需要ASCII字母a-z和A-Z。
int unique_chars(char* my_str) {
//printf("starting unique_chars\n");
char seen_buffer[52]; // max 52 letters a-z & A-Z
int seen_count = 1; // not ever expecting my_str to be NULL
int i, j;
char next;
//printf("first char is %c\n", my_str[0]);
seen_buffer[0] = my_str[0]; // first char must be unique
for (i=1; i<strlen(my_str); i++) { // walk along the rest of my_str
next = my_str[i];
if (next >= 97) {
next = next - 32; // the next char will always be capital, for convenience
}
for (j=0; j<seen_count; j++) { // compare next to all the unique chars seen before
//printf("current char is %c, checking against %c\n", next, seen_buffer[j]);
if ((next==seen_buffer[j]) || (next+32==seen_buffer[j])) {
//printf("breaking\n");
break; // jump to the next char in my_str if we find a match
}
if (j==seen_count-1) { // at this point, we're sure that next hasn't been seen yet
//printf("new unique char is %c\n", next);
seen_count++;
seen_buffer[seen_count] = next;
//printf("new char val is %c, should be %c\n", seen_buffer[seen_count], next);
break;
}
}
}
return seen_count;
}
int main(int argc, char* argv[]){
char* to_encode = argv[1];
printf("unique chars: %d\n", unique_chars(to_encode));
}
当我使用某些字符串调用时,结果不正确。例如,尝试:
./a.out gghhiijj
产生(printf未注释):
starting unique_chars
first char is g
current char is G, checking against g
breaking
current char is H, checking against g
new unique char is H
new char val is H, should be H
current char is H, checking against g
current char is H, checking against
new unique char is H
new char val is H, should be H
current char is I, checking against g
current char is I, checking against
current char is I, checking against H
new unique char is I
new char val is I, should be I
current char is I, checking against g
current char is I, checking against
current char is I, checking against H
current char is I, checking against H
new unique char is I
new char val is I, should be I
current char is J, checking against g
current char is J, checking against
current char is J, checking against H
current char is J, checking against H
current char is J, checking against I
new unique char is J
new char val is J, should be J
current char is J, checking against g
current char is J, checking against
current char is J, checking against H
current char is J, checking against H
current char is J, checking against I
current char is J, checking against I
new unique char is J
new char val is J, should be J
所以我一直在我的seen_buffer中得到重复项,因为有些空白字符存储在那里而不是应该存在的字母字符!然而,当我在写入seen_buffer之后立即进行比较(即新的字符是%c,应该是%c \ n)时,会显示正确的字符!
感谢任何帮助!
答案 0 :(得分:1)
这里有一个错误的错误:
seen_count++;
seen_buffer[seen_count] = next;
第一个字符进入seen_buffer[0]
,seen_count
设置为1.这意味着 next 新字符在seen_buffer[2]
之后进入seen_count
}增加到2. seen_buffer[1]
中没有任何内容(这是你在printfs中看到的空白字符),当你在seen_buffer
上检查一个字符时,你永远不会检查你刚才的最后一个字符投入。
交换这些行,它应该可以工作。
答案 1 :(得分:0)
您没有检查输入的值是否介于A到Z和a到z
之间你当前的代码也可以在char上看到缓冲区溢出see_buffer [52]所以在代码中添加边界检查
我认为您的代码可以非常直接
这是一个简单的算法
unsigned int returnUniqueChar (const char *input)
{
int count[52] = {0}; // initialize all the memory with zero
int unique = 0;
while (*input != '\0')
{
if ( (input >= 'A' && input <= 'Z')
{
count[input -'A']++;
}
else if (input >= 'a' && input <= 'z')
{
count[input -'a'+ 26]++;
}
input++;
}
for (int i = 0; i < 56 && (count[i] == 1) ; i++ )
unique++;
return unique;
}