压缩--当出现连续相同的字符,用数字表示个数

flight_lcf 2008-06-16 01:54:37
记得在以前考程序员的时候,做过这样一道题,现在想找找不到了,谁有的话,帮帮。
题目大概是:
将一个字符串进行压缩,出现连续相同的字符,用数字表示个数,后面追加这个字符。
例如:
源字符串:rrttttttwwqrtttt
压缩后的字符串:2r6t2w1q1r4t

...全文
468 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
jmulxg 2008-06-17
  • 打赏
  • 举报
回复
的确不是很好的算法
比较推荐霍夫曼树编码
linxy2002 2008-06-17
  • 打赏
  • 举报
回复
应注意,输出仍然是字符串,重复个数大于9个的情况,即数字可能不止一位数



#include <iostream>
#include <vector>
#include <stack>

using namespace std;

char* IntToChar(char* a, int i)
{
int k=1;
stack<char> s;

while(i>=10)
{
s.push(i%10+'0');
i = i/10;
k++;
}
s.push(i+'0');
for(;k>0;--k)
{
*a++ = s.top();
s.pop();
}
return a;
}

char* ChangeString(char* a)
{
if(a == NULL) return NULL;

char* b = new char[strlen(a)];
char* rt = b;
int i = 1;
while(*a != '\0')
{
if(*a == *(a+1))
{
++i;
}
else
{
if(i != 1)
{
b = IntToChar(b, i);
*b++ = *a;
}
else
*b++ = *a;
i = 1;
}
a++;
}
*b = '\0';

return rt;
}

int main()
{
char a[] = "aaaaaaaaaaaaaaabcddddddde";

cout<<ChangeString(a)<<endl;

return 0;
}

码农自来也 2008-06-17
  • 打赏
  • 举报
回复
我昨天回复的东西怎么就没了呢?奇怪
楼主,你看看像这样用链表来保存压缩结果行不?
#include <stdio.h>
#include <stdlib.h>

struct result{
char alpha; //这个用来保存你正在统计数量的那个字符
int count; //这是该字符出现的次数
struct result *next; //指向下一个统计结果的指针
};

int main(){
char input[256]; //要压缩的串
char temp; //当前统计的字符
int i,cnt; //输入串的指示器和重复次数的计数器
struct result *head,*fence,*p; //链表指针
//输入压缩串以及初始化变量
scanf("%s",&input);
if('\0' == input[0])
return 0;
temp=input[0];
i=1,cnt=1;
head = (struct result*)malloc(sizeof(struct result));
fence = head;
head->alpha = temp;
//开始压缩
while(input[i]!='\0'){
if(temp != input[i]){
//更新重复的个数
fence->count = cnt;
//开辟下一个链表成员
p =(struct result*)malloc(sizeof(struct result));
fence->next = p;
fence = fence->next;
fence->alpha = input[i];
fence->next = NULL;
//中间变量复位
temp = input[i];
cnt = 1;
p=NULL;
}//if
else{
cnt++;
}//else
i++;
}//while
fence->count = cnt; //更新最后一个字符的重复次数

//显示压缩结果
printf("\n源字符串:%s",input);
printf("\n压缩后的字符串:");
p=head;
while(p!=NULL){
if(p->count == 1)
printf("%c",p->alpha);
else
printf("%d%c",p->count,p->alpha);
p=p->next;
}
putchar('\n');

return 0;
}//main
码农自来也 2008-06-16
  • 打赏
  • 举报
回复
给出我写的愚钝的代码。这样做的话,当要压缩的串很短时,压缩可能要比不压缩还要占空间
#include <stdio.h>
#include <stdlib.h>

struct result{
char alpha; //这个用来保存你正在统计数量的那个字符
int count; //这是该字符出现的次数
struct result *next; //指向下一个统计结果的指针
};

int main(){
char input[256]; //要压缩的串
char temp; //当前统计的字符
int i,cnt; //输入串的指示器和重复次数的计数器
struct result *head,*fence,*p; //链表指针
//输入压缩串以及初始化变量
scanf("%s",&input);
if('\0' == input[0])
return 0;
temp=input[0];
i=1,cnt=1;
head = (struct result*)malloc(sizeof(struct result));
fence = head;
head->alpha = temp;
//开始压缩
while(input[i]!='\0'){
if(temp != input[i]){
//更新重复的个数
fence->count = cnt;
//开辟下一个链表成员
p =(struct result*)malloc(sizeof(struct result));
fence->next = p;
fence = fence->next;
fence->alpha = input[i];
fence->next = NULL;
//中间变量复位
temp = input[i];
cnt = 1;
p=NULL;
}//if
else{
cnt++;
}//else
i++;
}//while
fence->count = cnt; //更新最后一个字符的重复次数

//显示压缩结果
printf("\n源字符串:%s",input);
printf("\n压缩后的字符串:");
p=head;
while(p!=NULL){
if(p->count == 1)
printf("%c",p->alpha);
else
printf("%d%c",p->count,p->alpha);
p=p->next;
}
putchar('\n');

return 0;
}//main
码农自来也 2008-06-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 tailzhou 的回复:]
还有,他这里的字符串本身不能包含有数字,不然解压就有问题了;
[/Quote]
楼主,就算你这个题目的字符串中有数字其实也没所谓的,你可以用
struct result{
char alpha; //这个用来保存你正在统计数量的那个字符
int count; //这是该字符出现的次数
struct result *next; //指向下一个统计结果的指针
}
这样一个结构体组成的链表来保存你统计字符的结果啊,这样就不用担心解压的时候会因为多余字符而出现咯。至于算法和楼上的差不多,你自己实现吧。
oo 2008-06-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 tailzhou 的回复:]
还有,他这里的字符串本身不能包含有数字,不然解压就有问题了;
[/Quote]

可以这样的,一个字节表示个数,后面跟字符
如果表示个数的高字节为0,表示是重复字符
如果表示个数的高字节为1,去掉高位的其他bits表示后面有多少个字符没有重复

这样如果重复字符少,多余的字节也不会太多
源字符串:rrttttttwwqrtttt
压缩后的字符串:2r 6t 2w 130qr 4t
可口可乐 2008-06-16
  • 打赏
  • 举报
回复
简单的统计一下相邻重复字符出现的次数就可以了


#include <iostream>
#include <string>
#include <sstream>
using namespace std;

string compress(string& str)
{
int size = (int)str.size();
if (size == 0) return "";

ostringstream stream;
int num = 1;
for (int i = 1; i < size; i++) {
if (str[i] != str[i-1]) {stream << num << str[i-1]; num=1;}
else num++;
}
stream << num << str[size-1];
return stream.str();
}

int main()
{
cout << compress(string("rrttttttwwqrtttt")) << endl;
}


tailzhou 2008-06-16
  • 打赏
  • 举报
回复
还有,他这里的字符串本身不能包含有数字,不然解压就有问题了;
tailzhou 2008-06-16
  • 打赏
  • 举报
回复
可以修改成:如果不重复,字母前不添加数字,这样不可能更大;

例如:
源字符串:rrttttttwwqrtttt
压缩后的字符串:2r6t2wqr4t
flight_lcf 2008-06-16
  • 打赏
  • 举报
回复
这个只是一个考题,呵呵
oo 2008-06-16
  • 打赏
  • 举报
回复
这个没什么难度吧,不过如果重复的少,压缩效果会很差,还会比压缩前更大
flight_lcf 2008-06-16
  • 打赏
  • 举报
回复
我给了50分,怎么发帖后是0分阿。
因为出现了如上的问题,我明天(今天系统不允许加分)给此帖加50分。

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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