题目要求:
给定一个字符串,仅由a,b,c 3种小写字母组成。当出现连续两个不同的字母时,你可以用另外一个字母替换它,如 有ab或ba连续出现,你把它们替换为字母c; 有ac或ca连续出现时,你可以把它们替换为字母b; 有bc或cb 连续出现时,你可以把它们替换为字母a。 你可以不断反复按照这个规则进行替换,你的目标是使得最终结果所得到的字符串尽可能短,求最终结果的最短长度。
题目分析:
输入:字符串。长度不超过200,仅由abc三种小写字母组成。 输出: 按照上述规则不断消除替换,所得到的字符串最短的长度。 例如:输入cab,输出2。因为我们可以把它变为bb或者变为cc。 输入bcab,输出1。尽管我们可以把它变为aab -> ac -> b,也可以把它变为bbb,但因为前者长度更短,所以输出1。
在字符串消除的过程中关键在于处理类似:acbb的情况,这种情况下,不能简化为bbb而应该是aab。遇到这种情况我们可以分两种情况处理:首先,找到第一个与其后面字符不一致的字符,记录该字符的位置,并执行替换操作,得到子串(1)。其次,从第一次得出的字符位置后面一个开始查找与其不一致的字符,若没有找到不一致的字符,则递归对字符串(1)处理,如果找到这样一个位置则得出子串(2)。从第一次查找到的字符的位置后一个位置开始比较子串(1)和(2)。取相同字符少的子串进行处理。依次递归,直到子串中所有的字符都相同的时候,返回最终子串的长度。
举例:1>输入acbb,第一个与其后面字符不一致的字符为a,索引为0,替换得到子串1:bbb
2>从步骤1>中a的索引后面一个位置也就是c开始查找与c字符不一致字符的位置,找到了b字符,替换得到子串2:aab
3>从第一个查找到的字符位置后一个位置开始比较子串(1)和(2),这里也就是0的后面就是1的位置开始比较,子串1为bb,子串2为ab从而舍弃相同字符比较多的bbb
4>递归对(3)得到的子串处理直到字符串所有字符都相等的时候。
示例代码:
查找替换:
char turn ( char c1 , char c2 )
{
return 'a' + 'b' + 'c' - c1 - c2 ;
}
void reduce( char * st , char * ss , unsigned i )
{
strncpy( st , ss , i );
st[i] = turn ( ss[i] , ss[i+1] );
strcpy( st + i + 1 , ss + i + 2 );
}
int swap_str(char *pcStr, char* psDst, int nIndex)
{
while(pcStr[nIndex] != '\0' && pcStr[nIndex + 1] != '\0')
{
if(pcStr[nIndex] != pcStr[nIndex + 1])
{
reduce(psDst, pcStr, nIndex);
break;
}
nIndex++;
}
if(pcStr[nIndex] != '\0')
{
return (nIndex);
}
else
{
return -1;
}
}
计算相同字符个数:
int count_same_chars(const char* str)
{
if(str != NULL)
{
int nCount = 0;
char c = *str;
while((*str != '\0') && (c == *str))
{
str++;
nCount++;
}
return (nCount);
}
return (-1);
}
min_length函数:
int min_length(const char* str)
{
int nCount = 0;
int nIndex = 0;
char acSubStr1[256] = {0};
char acSubStr2[256] = {0};
printf("string :%s\n", str);
nCount = count_same_chars(str);
if(nCount == strlen(str))
{
return (nCount);
}
nIndex = swap_str(str, acSubStr1, 0);
if(nIndex >= 0)
{
swap_str(str, acSubStr2, nIndex + 1);
}
if(acSubStr2[0] == '\0')
{
return (min_length(acSubStr1));
}
else if(count_same_chars(acSubStr1 + nIndex + 1) > count_same_chars(acSubStr2 + nIndex + 1))
{
return (min_length(acSubStr2));
}
else
{
return (min_length(acSubStr1));
}
return (-1);
}
测试输出:
int main()
{
int nIndex= 0;
char *test[] = {
"abc",
"bacb",
"bbb",
"acbb",
"acbbb",
};
for(nIndex = 0; nIndex < sizeof(test)/sizeof(test[0]); nIndex++)
{
min_length(test[nIndex]);
printf("\n");
}
}
3617

被折叠的 条评论
为什么被折叠?



