删除相邻相同字符

c*s*d*n 2010-03-06 12:51:56
如:abbcd 变为 acd
abbbc 变为 ac
abbac 变为 c
...全文
592 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
ForestDB 2010-03-09
  • 打赏
  • 举报
回复
我的代码(23L)到底满足否?
LZ倒是给个答案啊。
huanmie_09 2010-03-09
  • 打赏
  • 举报
回复
引用 35 楼 dutysmart 的回复:
abbac 不能处理吧?

引用 19 楼 huanmie_09 的回复:<br /> 仅供参考: <br /> C/C++ code <br /> #include <stdio.h> <br /> #include <string.h>int main() <br /> {char s[255], d[255];int i, j, k=0, len;char ch; <br />     scanf("%s", s); <br />     len= strlen(s);for(i=0; i < len; i= j) {/*对字符串s进行遍历*/ <br />         ch= s[i];/*分别拿s[i]后面的字符与s[i]进行比较, 如果相等, 则移向下一个字符进行比较.*/for(j= i+1; ch== s[j]&& j < len; j++);/*如果参与比较的字符个数小于2, 则说明相邻元素间不存在相同元素,加入目标数组*/if(j- i <2) { <br />             d[k++]= ch; <br />         } <br />     } <br />     d[k]='\0'; <br />     printf("%s\n", d);return0; <br /> } <br />


修改了一下:

#include<stdio.h>
#include<string.h>

int main()
{
char s[255], d[255];
int i, j, k = 0, len;
char ch;
int flag = 0; /*增加标志标量, 初始化为0*/
scanf("%s", s);
len = strlen(s);
while(!flag) {
len = strlen(s);
for(i = 0; i < len; i = j) { /*对字符串s进行遍历*/
ch = s[i];

/*分别拿s[i]后面的字符与s[i]进行比较, 如果相等, 则移向下一个字符进行比较.*/
for(j = i + 1; ch == s[j] && j < len; j++);
/*如果参与比较的字符个数小于2, 则说明相邻元素间不存在相同元素,加入目标数组*/
if(j - i < 2) {
d[k++] = ch;
}
}
d[k] = '\0';

/*源串s与目标串d长度比较, 如果不相等,说明该趟去重中有重复字符,再进行一次去重*/
/*直到源串和目的串的长度相等*/
if(strlen(d) != len) {
strcpy(s, d);
k = 0;
}
else { /*源串与目的串长度相等, 说明目的串中相邻元素间已经没有重复字符*/
flag = 1; /*置标志, 退出循环*/
}
}
printf("%s\n", d);
return 0;
}

canyingwushang 2010-03-09
  • 打赏
  • 举报
回复
引用 38 楼 forestdb 的回复:
我的代码(23L)到底满足否?
LZ倒是给个答案啊。

大哥你的代码可以优化一下:

void foo(char * s, char * result)
{
char * base = result;
char * top = result;
char c;
int l = strlen(s);
int i;
int dup = 0;
for (i = 0; i <= l; i++)
{
c = s[i];
if (base == top)
{
*top++ = c;
continue;
}
if(c == *(top - 1))
{
*top++ = c;
dup += 1;//dup采用自加的方式记录重复次数
continue;
}
if(c != *(top - 1) && dup)
{
top=top-dup-1;//top直接移动,代替while循环
if (c == *(top - 1))
dup = 1;
else
dup = 0;
*top++ = c;
continue;
}
if (c != *(top - 1) && !dup)
{
*top++ = c;
continue;
}
}
}
flyyyri 2010-03-07
  • 打赏
  • 举报
回复
ding
引用 20 楼 gaslinux 的回复:
这是我用hash算法做的,应该算是效率比较高的,当然需要用到另外的空间。

#include <stdio.h>
int main(int argc,char *argv[])
{
        int count[128]={0};
char s[32]="aabcdefgggfeds";
int i=0,j=0;

for(;s[i]!=0;i++)
count[s[i]]++;

for(i=0;s[i]!=0;i++)
{
if(count[s[i]]==1)
{
s[j]=s[i];
j++;
}
}
        s[j]=0;
   
printf("%s\n",s);
     

return 0;

}
c*s*d*n 2010-03-07
  • 打赏
  • 举报
回复
abbac 不能处理吧?

引用 19 楼 huanmie_09 的回复:
仅供参考:
C/C++ code
#include<stdio.h>
#include<string.h>int main()
{char s[255], d[255];int i, j, k=0, len;char ch;
scanf("%s", s);
len= strlen(s);for(i=0; i< len; i= j) {/*对字符串s进行遍历*/
ch= s[i];/*分别拿s[i]后面的字符与s[i]进行比较, 如果相等, 则移向下一个字符进行比较.*/for(j= i+1; ch== s[j]&& j< len; j++);/*如果参与比较的字符个数小于2, 则说明相邻元素间不存在相同元素,加入目标数组*/if(j- i<2) {
d[k++]= ch;
}
}
d[k]='\0';
printf("%s\n", d);return0;
}
c*s*d*n 2010-03-07
  • 打赏
  • 举报
回复
abba这样不能处理吧

引用 25 楼 gelu1040 的回复:
C/C++ codeint caonima(char*s)
{if(s==NULL)return0;int i=0;while(s[i]!=0)
{
s[i]=s[i+1];
i++;
}return1;
}int rinima(char*s)
{if(s==NULL)return0;char*p=s;while(*p!=0)
{if(*p=?-
c*s*d*n 2010-03-07
  • 打赏
  • 举报
回复
abbaac 好像就不可以处理吧?

引用 30 楼 keiy 的回复:
改进过的,也用24#的测试,没问题了:
C/C++ code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
main()
{char buff[200];int i,j;char oldc,oldc1;char dest[200];

oldc=oldc1=0;
scanf("%s",buff);
j=0;for(i=0;i<strlen(buff);i++)
{if (buff[i]!=oldc)
{
oldc=buff[i];if (j)
{if(dest[j-1]==oldc)
{
j--;continue;
}
}
dest[j++]=oldc;

}else
{if (oldc!=oldc1)
{
j--;

oldc1=oldc;
}
}
}
dest[j]=0;
printf("%s\n",dest);
system("pause");
}
小魔菇 2010-03-07
  • 打赏
  • 举报
回复
我觉得用栈来处理比较好
musiclee 2010-03-07
  • 打赏
  • 举报
回复
引用 29 楼 gaslinux 的回复:
引用 26 楼 musiclee 的回复:呵呵  确实没看清楚要求。。但这个方法依然可行啊 只要改成遇到一个和新数组中的最后一个相同 则删掉最后一个呗。。。。。。

很遗憾,还是没看清,不过楼主的标题也太容易误导了。

好吧我承认 我彻底没看清。。。在改改。。一直相同则继续找一样的 知道找到不一样的 ,然后在删
cy330206 2010-03-06
  • 打赏
  • 举报
回复
用个指针来当索引然后比较前后字母是不是相同,不相同的可以放进一个数组里面,相同的可以是不去管它再指向下一个字节
柯本 2010-03-06
  • 打赏
  • 举报
回复
改进过的,也用24#的测试,没问题了:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
main()
{
char buff[200];
int i,j;
char oldc,oldc1;
char dest[200];

oldc=oldc1=0;
scanf("%s",buff);
j=0;
for(i=0;i<strlen(buff);i++)
{
if (buff[i]!=oldc)
{
oldc=buff[i];
if (j)
{
if(dest[j-1]==oldc)
{
j--;
continue;
}
}
dest[j++]=oldc;

}
else
{
if (oldc!=oldc1)
{
j--;

oldc1=oldc;
}
}
}
dest[j]=0;
printf("%s\n",dest);
system("pause");
}


gaslinux 2010-03-06
  • 打赏
  • 举报
回复
引用 26 楼 musiclee 的回复:
呵呵  确实没看清楚要求。。但这个方法依然可行啊 只要改成遇到一个和新数组中的最后一个相同 则删掉最后一个呗。。。。。。


很遗憾,还是没看清,不过楼主的标题也太容易误导了。
柯本 2010-03-06
  • 打赏
  • 举报
回复
引用 27 楼 dutysmart 的回复:
accab 你也全部测过吗  输出 aab

不好意思,这种情况没考虑到
c*s*d*n 2010-03-06
  • 打赏
  • 举报
回复
accab 你也全部测过吗 输出 aab

引用 10 楼 keiy 的回复:
引用 7 楼 dutysmart 的回复:00a这种情况没处理吧?
当然没问题,就是000也可以,我全部测试过
musiclee 2010-03-06
  • 打赏
  • 举报
回复
引用 17 楼 gaslinux 的回复:
引用 16 楼 pang123hui 的回复:<br /> 引用 11 楼 musiclee 的回复:在新创建一个数字呗,遍历原数组,遇到一个加一个  有相同的不加 不就得了呗 <br /> <br /> 恩,我也是这样想的,鉴于这是C区,给个纯C代码 <br />
晕,这么多不看清要求的。


呵呵 确实没看清楚要求。。但这个方法依然可行啊 只要改成遇到一个和新数组中的最后一个相同 则删掉最后一个呗。。。。。。
gelu1040 2010-03-06
  • 打赏
  • 举报
回复

int caonima(char *s)
{
if(s==NULL)
return 0;
int i=0;
while(s[i]!=0)
{
s[i]=s[i+1];
i++;
}
return 1;
}

int rinima(char *s)
{
if(s==NULL)
return 0;
char *p=s;
while(*p!=0)
{
if(*p==*(p+1))
{
caonima(p);
}
else
p++;
}
return 1;
}

int main(int argc, char* argv[])
{
char s[]="absfajkdcsssnjaaaa";
rinima((char*)s);
puts(s);

return 0;
}


ForestDB 2010-03-06
  • 打赏
  • 举报
回复
以下是些测试用例。

$ ./x abc
3: abc
abc
$ ./x aabbcc
6: aabbcc

$ ./x abbacc
6: abbacc

$ ./x abccba
6: abccba

$ ./x abbbac
6: abbbac
c
ForestDB 2010-03-06
  • 打赏
  • 举报
回复
引用楼主 dutysmart 的回复:
如:abbcd 变为 acd
    abbbc 变为 ac
    abbac 变为 c

考虑到第2和3两种情况,特别是第3种情况,应该用栈来做比较好。
第二种情况是有连续多个相同字符
第三种情况是删掉连续字符后还有连续字符。

# include <stdio.h>
# include <stdlib.h>
# include <string.h>

void foo(char * s, char * result) // result为栈结构
{
char * base = result; // 栈底
char * top = result; // 栈顶
char c, popc; // c为当前字符,popc为弹出字符
int l = strlen(s); // 源字串长度
int i; // 循环用索引
int dup = 0; // 是否有重复标志位

for (i = 0; i <= l; i++) // 注意这里的<=,元字串中的'\0'也需要用来做压栈出栈的处理
{ // 以保证末尾有连续字符能够被正确处理(abcdd这样的字符)
// 得到当前字符
c = s[i]; // why l, i.e the \0 here, to make the stack complete
if (base == top) // 空栈,push c
{
*top++ = c;
continue;
}
if (c == *(top - 1)) // c等于栈顶,push c,置dup状态
{
*top++ = c;
dup = 1;
continue;
}
if (c != *(top - 1) && dup) // c不等于栈顶且dup置位,说明前面有重复字符
{
do {
popc = *--top;
} while (popc == *(top - 1)); // 这里先pop出重复的字符
if (c == *(top - 1)) // 如果c和新的栈顶相同,说明上述第三种情况出现
dup = 1; // 还是置dup状态
else
dup = 0;
*top++ = c;
continue;
}
if (c != *(top - 1) && !dup) // c不等于栈顶且没有dup状态,push c
{
*top++ = c;
continue;
}
}
}

int main(int argc, char * argv[])
{
if (argc != 2)
{
printf("Usage: %s \"a string\"\n", argv[0]);
exit(1);
}

{
int length = strlen(argv[1]);
char * result = (char *)calloc(length + 1, sizeof(char));

if (!result)
{
printf("allocation fail!\n");
exit(1);
}

printf("%d: %s\n", length, argv[1]);
foo(argv[1], result);
printf("%s\n", result);

free(result);
}

return 0;
}
mapeisarah 2010-03-06
  • 打赏
  • 举报
回复
接分~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hlm_87 2010-03-06
  • 打赏
  • 举报
回复
#include <iostream>
#include <string>

using namespace std;

/* 利用stl库函数的 */
void del_char()
{
string str("abbccdde");
string::size_type it = 0;
for(string::size_type i = 0; i < str.size();i++)
{
for(string::size_type j = i+1; j < str.size();j++)
{
if(str[i] != str[j])
{
if( i != j-1)
{
str.erase(i,j-i);
if(i != 0)i = i-2;
}
break;
}
}
}
cout << str << endl;
}

int main()
{
del_char();
}
加载更多回复(19)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧