两个小题目。
一个是:字符串里面只有字母和星号,要求把星号移动最左边,字母移动到最右边,要求复杂度尽可能低。
比如“a*b*c*d*”移动之后成为”****abcd”
这个题目有两个方法,首先就是暴力解法。从串尾或者串首判断(假设串尾),如果是星号则移动到串首起第一个不是星号的位置,然后把从那个位置开始的串统统后移一位到星号处。复杂度应该是 平方级。
这个方法的劣势就在于字母移动的位置可能不是最终位置。而下面这个方法是一步到位地令非星号移动到最终位置:
新增一个变量j表示当前已经移动的字母的下标,初始值为len-1,
然后从后面逆序扫描字符串,如果是星号则继续扫描,如果不是信号,则拷贝这个数据到j所在位置,同时j也自减。
这样一个周期走完之后,所有字母均移动好,剩下的就是把j个前位置全部重置为星号。这样复杂度只有O(N)
代码为:
bool check(char c)
{
return (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') ? true : false;
}
void move(char * p, int len)
{
int j = len - 1;
for (int i = len - 1; i >= 0; --i)
if (check(*(p + i)))
p[j--] = p[i];
while (j >= 0)
p[j--] = '*';
}
int main()
{
char a[11] = { "1234567890" };
move(a, 10);
cout << a << endl;
return 0;
}
第二题:给定一个母串和子串,要求删除所有和子串数据相同的字符,比如
“welcome to asted”模式串为”aeiou”结果要求为”wlcm t std”要求性能最优。
用上述的方法二,得到的代码为:
bool check(char c, char *pset, int setlen)
{//此处复杂度为O(setlen),若pset有序,则可以用二分查找,则复杂度将为O(log setlen)
while (setlen >= 0)
{
if (*(pset + setlen - 1) == c)
return true;
--setlen;
}
return false;
}
void move(char * p, int len, char *pset, int setlen)
{
int j = 0;
for (int i = 0; i < len; ++i)
if (!check(*(p + i),pset,setlen))
p[j++] = p[i];
p[j] = 0;
}
int main()
{
char a[] = { "welcome to asted" };
char b[] = { "aeiou" };
move(a, sizeof(a)-1, b, sizeof(b)-1);
cout << a << endl;
system("pause");
return 0;
}
全文完