【问题标题】:Find Every Position of a Given Char Within an Array查找给定字符在数组中的每个位置
【发布时间】:2012-10-05 14:39:57
【问题描述】:

我做了一个小函数,它填充一个分配的内存块,其中包含给定字符串中给定字符的每个位置,并返回一个指向内存块的指针。

这个函数唯一的问题是没有办法检查内存块的大小;所以我还做了一个函数来计算字符串中给定字符的出现次数。

这是一个使用示例:

/*count occurences of char within a given string*/
size_t strchroc(const char *str, const char ch)
{ 
    int c = 0;
    while(*str) if(*(str++) == ch) c++;
    return c;
}

/*build array of positions of given char occurences within a given string*/
int *chrpos(const char *str, const char ch)
{
    int *array, *tmp, c = 0, i = 0;

    if(!(array = malloc(strlen(str) * sizeof(int)))) return 0x00;
    while(str[c])
    {
        if(str[c] == ch) array[i++] = c;
        c++;
    }
    if(!(tmp = realloc(array, i * sizeof(int)))) return 0x00;
    array = tmp;
    return array;
}

int main(void)
{
    char *str = "foobar foobar";                //'o' occurs at str[1], str[2], str[8], and str[9]
    int *array, b = 0, d;

    if(!(array = chrpos(str, 'o'))) exit(1);    //array[0] = 1, array[1] = 2, array[2] = 8, array[3] = 9

    /*
     * This is okay since I know that 'o'
     * only occures 4 times in str. There
     * may however be cases where I do not
     * know how many times a given char 
     * occurs so I figure that out before
     * utilizing the contents of array.
     * I do this with my function strchroc.
     * Below is a sample of how I would 
     * utilize the data contained within
     * array. This simply prints out str
     * and on a new line prints the given
     * char's location within the str 
     * array
     */

    puts(str);
    while(b < (int) strchroc(str, 'o'))         //loop once for each 'o' 
    {
        for(d = 0; d < (b == 0 ? array[b] : array[b] - array[b - 1] - 1); d++) putc((int) ' ', stdout);
        printf("%d", array[b]);
        b++;
    }
}

输出:

foobar foobar
 12     89

我唯一担心的是,如果这两个功能之一失败,则无法正确使用数据。我正在考虑将字符串中char 的出现次数作为chrpos 的参数,但即便如此我仍然必须调用这两个函数。

我想知道是否有人对如何做到这一点有任何建议,这样我只需要一个函数来构建数组。

我能想到的唯一方法是将出现的字符数存储到array[0] 并让array[1] through array[char_occurences] 持有char 的位置。

如果有人有更好的想法,我将不胜感激。

【问题讨论】:

  • 不确定您如何使用最终结果 - 您是否真的需要构建完整列表以供将来使用,或者将您的方法切换到扫描仪(在此位置之后查找下一个出现的字符)锻炼?您必须传递更多(指针)变量来维护调用之间的状态,但如果这对您的最终用途有用,它将解决您正在查看的几个问题。
  • 只是在这种特殊情况下,我需要完整的列表,我想我只需要将字符数移动到数组 [0] 中。
  • 为什么让你认为这两个函数(我假设你说的是 chrpos 和 strchroc)会失败?
  • 更重要的是,如果 realloc 失败,你为什么不return array;
  • 如果没有malloc,您将无法执行此操作,因此chrpos 将始终存在此风险。 strchroc 在普通字符串上永远不会失败;如果您担心,您可以在取消引用之前测试str

标签: c char substring performance


【解决方案1】:

正如我的评论中所说,第一件事是无论如何都要保存数据,以防您无法缩小分配的内存:

if (!(tmp = realloc(array, i * sizeof(int))))
  return array;
return (tmp); //array = tmp; is useless

如果您想多一点保护您的 strchroc 函数,请在开头添加 if (!str) return 0;

【讨论】:

    【解决方案2】:

    您可以更改您的函数,使其也“返回”找到的出现次数。虽然我们实际上不能从 C 中的函数返回多个值,但我们可以将指针作为参数传递,并让函数使用该指针写下一个值:

    int *chrpos(const char *str, char ch, int *found) {
        /* 
        ...
        */
        *found = i;
        return array;
    }
    

    请注意,ch 不需要 const 修饰符。

    【讨论】:

    • 有趣的解决方案 :) 谢谢。
    猜你喜欢
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-12
    相关资源
    最近更新 更多