C 处理字符串的算法

C 处理字符串的算法,c,string,function,replace,variations,C,String,Function,Replace,Variations,我真的不知道如何实现这个功能: 函数应该获取指向整数的指针、指向字符串数组的指针以及进程的字符串。函数应将exchange“ch”组合的所有变体写入数组中的“@”符号,并将整数更改为此数组的大小。有一个处理示例: choker => {"choker","@oker"} chocho => {"chocho","@ocho","cho@o","@o@o"} chachacha => {"chachacha","@achacha","cha@acha","chacha@a",

我真的不知道如何实现这个功能: 函数应该获取指向整数的指针、指向字符串数组的指针以及进程的字符串。函数应将exchange“ch”组合的所有变体写入数组中的“@”符号,并将整数更改为此数组的大小。有一个处理示例:

choker => {"choker","@oker"}

chocho => {"chocho","@ocho","cho@o","@o@o"}

chachacha => {"chachacha","@achacha","cha@acha","chacha@a","@a@acha","cha@a@a","@acha@a","@a@a@a"}
我是用c标准99写的。这是草图:

int n;
char **arr;
char *string = "chacha";
func(&n,&arr,string);
和功能示意图:

int func(int *n,char ***arr, char *string) {

}

所以我想我需要创建另一个函数,它计算“ch”组合的数量,并为这个组合分配内存。我很高兴听到关于这个算法的任何想法。提前感谢。

您可以非常轻松地计算组合的数量:

char * tmp = string;
int i;
for(i = 0; *tmp != '\0'; i++){
    if(!(tmp = strstr(tmp, "ch")))
        break;
    tmp += 2; // Skip past the 2 characters "ch"
}

// i contains the number of times ch appears in the string.

int num_combinations = 1 << i;

// num_combinations contains the number of combinations. Since this is 2 to the power of the number of occurrences of "ch"
char*tmp=string;
int i;
对于(i=0;*tmp!='\0';i++){
如果(!(tmp=strstr(tmp,“ch”))
打破
tmp+=2;//跳过2个字符“ch”
}
//i包含ch在字符串中出现的次数。

int num_combinations=1首先,我要创建一个helper函数,例如countChs,它只需迭代字符串并返回“ch'-s”的数目。这应该很容易,因为不涉及字符串重叠

当您有出现次数时,需要为2^个计数字符串分配空间,每个字符串(除原始字符串外)的长度strlen(原始)-1。您还可以将n变量更改为等于该2^计数

分配完空间后,只需迭代新表中的所有索引,并用原始字符串的副本(要复制的strcpy()或strncpy())填充它们,然后将其中的“ch”替换为“@”(在线上有大量现成的代码段,只需查找“C string replace”)


最后,使您的arr指针指向新表。但是要小心-如果它以前指向其他数据,您应该考虑释放它,否则最终会导致内存泄漏。

如果您希望替换字符串的所有变体,数组大小将包含
2^n
元素。其中
n
-子字符串“ch”的数目。因此,计算如下:

int i = 0;
int n = 0;
while(string[i] != '\0')
{
    if(string[i] == 'c' && string[i + 1] == 'h')
        n++;

    i++;
}
然后我们可以用二进制表示数字。让我们注意,将整数从
0
增加到
2^n
,第i个数字的二进制表示将告诉我们,要更改哪个“ch”出现。因此:

for(long long unsigned int i = 0; i < (1 << n); i++)
{
    long long unsigned int number = i;
    int k = 0;

    while(number > 0)
    {
        if(number % 2 == 1)
            // Replace k-th occurence of "ch"

        number /= 2;
        k++;
    }

    // Add replaced string to array
}
for(长无符号整数i=0;i<(1 0)
{
如果(编号%2==1)
//替换第k次出现的“ch”
数目/=2;
k++;
}
//将替换的字符串添加到数组中
}
这段代码检查
数字
二进制表示形式中的每一位,如果第k位为1,则更改第k次出现。更改第k次“ch”非常简单,我将它留给您


此代码仅对64次或更少的事件有用,因为无符号的
long long int
只能保存
2^64
值。

对于原始问题,您需要解决两个子问题:

  • 为变体数组分配空间
  • 计算变化
对于第一个问题,您需要找到数学函数
f
,该函数获取输入字符串中出现的“ch”次数并返回总变化数。 根据你的例子:
f(1)=1
f(2)=4
f(3)=8
。这应该让你知道从哪里开始,但证明你的函数是正确的很重要。归纳法是一种很好的证明方法

由于替换过程确保结果的长度与原始结果的长度相同或较低,因此可以为每个单独的结果分配与原始结果长度相等的空间

至于第二个问题,最简单的方法是使用递归,就像nightlytrails提供的示例一样

您需要另一个函数,该函数获取为结果分配的数组、结果的
计数、字符串的当前状态以及当前字符串中的
索引

调用时,如果在
索引
之外不再出现“ch”,则将结果保存在数组中的
计数
位置,并递增
计数
(以便下次不覆盖以前的结果)

如果在
索引
之外有任何“ch”,则调用此函数两次(重复部分)。其中一个调用使用当前字符串的副本,并且仅将
索引
增加到刚好超出“ch”的位置。另一个调用使用当前字符串的副本,其中“ch”替换为“@”并将
索引增加到“@”之外

确保没有内存泄漏。如果没有匹配的
free
,则没有
malloc
。 在您使用此解决方案后,您可能会注意到它的内存不足。它使用的内存超出了应有的范围。改进算法是读者的一项练习。

查看此链接。您可以围绕它对算法进行建模。