例如输入字符串:AAABBBBCCCCCC,要求输出:A3B4C6.我写的程序如下,可是出现了错误,谁能帮我看看

jarlly2011 2011-07-26 07:57:15
例如输入字符串:AAABBBBCCCCCC,要求输出:A3B4C6.我写的程序如下,可是出现了错误,谁能帮我看看.

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

void get_same_num(char* Dest,const char* src)
{
int lenght = strlen( src ) ;
printf("======%d====",lenght);
Dest = new char[lenght+1];
int j =0 ;
for ( int i = 0 ; i < lenght+1 ; i++ )
{
int adr ;
int num = 0;
for ( adr = 0 ; adr < lenght + 1 ; adr++ )
{
if ( src[i] == src[adr] )
{
num ++;
printf("======%d\n",num);
}
else
{
printf("=========%d========\n",num);
Dest[j] = src[i];
char c_num = NULL;
sprintf(&c_num,"%d",num);
Dest[j+1] = c_num;
}
}
j=j+2;
i = i + num - 1;
}
printf(Dest);
}

int main( )
{
char * Dest = NULL;
get_same_num(Dest,"AAABBBBCCCCCC");
return 0;
}
那位高手还有什么更好的方法可以分享分享哦。
...全文
1584 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
horin153 2011-07-28
  • 打赏
  • 举报
回复
几年没有在csdn论坛逛了,我也来回复下:

首先是需求分析,贴主的问题显然描述不清晰。
1,对字符串进行编码后,是否需要进行可逆的解码?
2,字符串输入集是英文字母?还是 ASCII 字符?是否有汉字等多字节字?
假设字符串需要可逆解码,如果输入是英文字母,则 A123 是无歧义的;如果是 ASCII 字符,则 A123 是有歧义的(A222 或者 123个连续A)。为简化问题,假设是没有汉字的纯 ASCII 字符串(当然包括了字母集)。

接着是设计。对 ASCII 字符串进行编码,因为字符的重复次数未定,为了节约空间,定义编码后的数据结构为:
字符/byte + 字符重复数(最大255)/byte
对连续 260 个 A 的字符串,编码后内存数据为:'A',0xFF,'A',0x05,也就是占用 4 字节(255个A,5个A);在可视化输出时可以处理为 A:260。

最后就是代码实现和单元测试。对这个简单的字符串问题,用标准库就足够了,代码如下:

//---------------------------- code begin ----------------------------
#include <string.h>
#include <assert.h>
#include <stdio.h>

void encode(char* dst, char* src) {
assert(dst);
assert(src);
unsigned char n=0;
char *ps=src, *pd=dst, *p=src;
while (*p++) {
if ((*ps!=*p) || (p-ps==0xff)) {
*pd++ = *ps;
n = p - ps;
ps = p;
*pd++ = *((char*)&n);
}
}
*pd = '\0';
}

int main(void) {
char src[301] = {0}; // 最长为300的字符串
::memset(src, 'A', 260); // 连续260个A
char* p = src;
p += 260;
::memset(p, 'B', 40); // 接着连续40个B
size_t len = 300*2+1; // 输出字符串长度为输入字符串长度的 2 倍
char* dst = new char[len];
::memset(dst, 0, len);
encode(dst, src);

// 把编码后的内存数据打印出来, 很容易就可以改为解码算法.
printf ("After encode:");
p = dst;
while(*p && *(p+1)) {
printf ("%c:%d;", *p, *((unsigned char*)(p+1)));
p += 2;
}
delete[] dst;

return 0;
}
//---------------------------- code end ----------------------------

测试输出结果如下:
After encode:A:255;A:5;B:40;
这和输入的字符数是一致的,测试正确。


这个回复我也写入了我的博客:
http://blog.csdn.net/horin153/article/details/6640507
赵4老师 2011-07-27
  • 打赏
  • 举报
回复
记不得哪位C++大牛在哪本学习C++的书的前言里面说过
“用C语言1000行源码能完成的工作千万不要用C++重写!”
deping_chen 2011-07-27
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include <sal.h>
#include <crtdbg.h>
#include <string.h>
#include <malloc.h>

//caller should be responsible for release return memory by free function.
char* simple_compress(__in_z const char* source)
{
_ASSERTE(source != NULL);
int len = strlen(source);

//allocate enough memory for any conditions.
char* result = (char*)malloc(2*len+1);
if(result == NULL)
return NULL;

//initilize
*result = '\0';
char* buffer = result;
char head = *source;
int count = 1;

for(int i=1;i<=len;++i)
{
if(head != *(source+i))
{
int writtenCount = sprintf(buffer, "%c%d", head, count);
buffer += writtenCount;

head = *(source+i);
count = 1;
}
else
{
++count;
}

if(*source == '\0')
break;
}
return result;
}

void test(const char* source)
{
printf("%s ==> ", source);
char* result = simple_compress(source);
printf("%s\n", result);
free(result);
}

int _tmain(int argc, _TCHAR* argv[])
{
test("");
test("A");
test("AA");
test("AABB");
return 0;
}
deping_chen 2011-07-27
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include <sal.h>
#include <crtdbg.h>
#include <string.h>
#include <malloc.h>

//caller should be responsible for release return memory by free function.
char* simple_compress(__in_z const char* source)
{
_ASSERTE(source != NULL);
int len = strlen(source);

//allocate enough memory for any conditions.
char* result = (char*)malloc(2*len+1);
if(result == NULL)
return NULL;

//initilize
*result = '\0';
char* buffer = result;
char head = *source;
int count = 1;

for(int i=1;i<=len;++i)
{
if(head != *(source+i))
{
int writtenCount = sprintf(buffer, "%c%d", head, count);
buffer += writtenCount;

head = *(source+i);
count = 1;
}
else
{
++count;
}

if(*source == '\0')
break;
}
return result;
}

void test(const char* source)
{
printf("%s ==> ", source);
char* result = simple_compress(source);
printf("%s\n", result);
free(result);
}

int _tmain(int argc, _TCHAR* argv[])
{
test("");
test("A");
test("AA");
test("AABB");
return 0;
}

deping_chen 2011-07-27
  • 打赏
  • 举报
回复
看到这一行,
Dest = new char[lenght+1];
你的内存泄漏了。外面接不到你的输出字符串,请把Dest改成char**。
samyou 2011-07-27
  • 打赏
  • 举报
回复
用正则表达式
郑恪文 2011-07-26
  • 打赏
  • 举报
回复
在补充两点:我说用map的时候想的是不对的,map中的元素不能重复而且会打乱字符原来的出现顺序; 楼主原代码之中new的内存没有释放 哦~~
郑恪文 2011-07-26
  • 打赏
  • 举报
回复

#include <vector>
#include <stdio.h>

//算法所使用的数据结构,
// m_cCharactor表示当前的字符
// m_iRptTime表示字符重复的次数
class Node
{
public:
Node(char c, int i)
: m_cCharactor(c)
, m_iRptTimes(i)
{};
~Node() {};

char m_cCharactor;
int m_iRptTimes;
};

typedef std::vector<Node> StatisticVec;

void get_same_num(const char* src, StatisticVec& output)
{
for ( int i = 0; src[i] != '\0'; i++ )
{
if( output.empty() ) //初始条件下,将第一个字符节点放进vector
output.push_back( Node(src[i], 1) );
else if ( output.back().m_cCharactor == src[i] ) //如果当前的字符与vector末尾字符一致,则增 加该节点的计数。
output.back().m_iRptTimes++;
else //否则,为vector增加一个新的节点
output.push_back( Node(src[i], 1) );
}
}

int main()
{
StatisticVec resultvec;
get_same_num("AAABBBBCCCCCCCC", resultvec);

//算法输出部分与楼主有点不一样
for (int i = 0; i < resultvec.size(); ++i)
printf("%c%d", resultvec[i].m_cCharactor, resultvec[i].m_iRptTimes);

return 0;
}


以上代码在ubuntu, g++ 下测试过了。

此外,刚才的回复有点不对:
前两条是不对的,楼主对i的控制虽然繁琐但是是正确的。 只需要将
(1)char c_num改成char c_num[8],
(2)然后将sprintf中的取地址算符&去掉,
(3)Dest[j+1] = c_num[0]就行了。注: 此处有缺陷,只能对重复次数小于10的情况成立。
原因我觉得是:原代码中的sprintf使内存越界了。
luciferisnotsatan 2011-07-26
  • 打赏
  • 举报
回复
C++,直接用STL的count函数
hndcwynui 2011-07-26
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void get_same_num(char* Dest, const char* src)
{
int i, j, k;
int length = strlen(src);
Dest = new char[2 * length+1];
Dest[0] = '\0';
for (i = 1, j = 1; i < length ; i++) {
if (src[i] == src[i-1]) {
j++;
} else {
k = strlen(Dest);
sprintf(Dest + k, "%c%d", src[i-1], j);
j = 1;
}
}
k = strlen(Dest);
sprintf(Dest + k, "%c%d", src[i-1], j);
printf(Dest);
}

int main( )
{
char * Dest = NULL;
get_same_num(Dest,"AAABBBBCCCCCC");
return 0;
}
Gloveing 2011-07-26
  • 打赏
  • 举报
回复
比较前一个字符和下一个字符,相同就个数加一,不同就清为一,在继续统计
Gloveing 2011-07-26
  • 打赏
  • 举报
回复
比较前一个字符和下一个字符,相同就个数加一,不同就清为一,在继续统计
郑恪文 2011-07-26
  • 打赏
  • 举报
回复
总算看懂了楼主的算法,
我看到了3个问题:
1. 内层循环的起始条件应该是从i 开始,不是0
2. 外层循环的 ++i是多余的
3. else
{
printf("=========%d========\n",num);
Dest[j] = src[i];
char c_num = NULL;
sprintf(&c_num,"%d",num);
Dest[j+1] = c_num;
}
这个地方的snprintf用的不对,污染了内存数据。这是最严重的,我不知道为啥能通过编译,但是我的运行结果是你的lenght到这里以后就变成0了。直接退出外层循环。

建议:
用map能写出一个简洁的demo.晚上回去再继续……
TitanQuest 2011-07-26
  • 打赏
  • 举报
回复
把原作糟蹋了,哎
TitanQuest 2011-07-26
  • 打赏
  • 举报
回复
呵呵,恩
赵4老师 2011-07-26
  • 打赏
  • 举报
回复
“调用malloc不判断返回NULL”
至少和
“定义char c[100]不判断是否访问c[i],i≥100”
一样危险!
TitanQuest 2011-07-26
  • 打赏
  • 举报
回复

#include <stdio.h>
#include <stdlib.h>
#include <String.h>
#include <ctype.h>

void Press(char *psrc){
char *pc1 = psrc, *pc2 = psrc;
int icount = 1;
while(*pc1){
if(*(pc1 + 1) != *pc1){
if(icount - 1){
char ca[10] = {0};
pc2++;
itoa(icount , ca, 10);
memcpy(pc2, ca, strlen(ca));
pc2 += strlen(ca);
*pc2 = *(pc1 + 1);
}else{
pc2++;
*pc2 = *(pc1 + 1);
}
icount = 0;
}
icount++;
pc1++;
}
return;
}

char* UnPress(char *psrc){
int icount = 0, inewlen = 1, in = 0, i = 0;
char *pctmp = psrc, *pc = NULL, *p = NULL, c, ca[10] = {0};
while(*pctmp){
if(isalpha(*pctmp)){
inewlen++;
in = atoi(ca) - 1;
memset(ca, 0, 10);
inewlen += in;
icount = 0;
}
if(isdigit(*pctmp)){
ca[icount] = *pctmp;
icount++;
}
pctmp++;
}
in = atoi(ca);
inewlen += in;

pc = (char *)malloc(inewlen);
memset(pc, 0, inewlen);
icount = 0;
in = 0;
memset(ca, 0, 10);
pctmp = psrc;
p = pc;
while(*pctmp){
if(isalpha(*pctmp)){
in = atoi(ca);
memset(ca, 0, 10);
icount = 0;
for(i = 0; i < in - 1; i++){
*p = c;
p++;
}
c = *pctmp;
*p = c;
p++;
}
if(isdigit(*pctmp)){
ca[icount] = *pctmp;
icount++;
}
pctmp++;
}

in = atoi(ca);
for(i = 0; i < in - 1; i++){
*p = c;
p++;
}
/*解压比压缩麻烦些,长度肯定不够*/
return pc;
}

void main(){
char s[]="AAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCde", *su = NULL;
Press(s);
printf("%s\n",s);
su = UnPress(s);
printf("%s", su);
if(su)
free(su);
getch();
return;
}

向楼上大哥学习,把解压的补上,呵呵,写的比较丑陋 ^_^


赵4老师 2011-07-26
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 hello456 的回复:]
做一个细心的程序员 真辛苦 考虑的问题真多
[/Quote]
理解万岁!
HELLO456 2011-07-26
  • 打赏
  • 举报
回复
做一个细心的程序员 真辛苦 考虑的问题真多
TitanQuest 2011-07-26
  • 打赏
  • 举报
回复
呵呵,的确能,刚才眼睛看错了,
还有一点区别,原串压缩和非原串压缩,
那个没有解压,你有解压,
呵呵,这次总结全了,
加载更多回复(7)
基于tensorflow2.x卷积神经网络字符型验证码识别 卷积神经网络(Convolutional Neural Networks, CNNs 或 ConvNets)是一类深度神经网络,特别擅长处理图像相关的机器学习和深度学习任务。它们的名称来源于网络中使用了一种叫做卷积的数学运算。以下是卷积神经网络的一些关键组件和特性: 卷积层(Convolutional Layer): 卷积层是CNN的核心组件。它们通过一组可学习的滤波器(或称为卷积核、卷积器)在输入图像(或上一层的输出特征图)上滑动来工作。 滤波器和图像之间的卷积操作生成输出特征图,该特征图反映了滤波器所捕捉的局部图像特性(如边缘、角点等)。 通过使用多个滤波器,卷积层可以提取输入图像中的多种特征。 激活函数(Activation Function): 在卷积操作之后,通常会应用一个激活函数(如ReLU、Sigmoid或tanh)来增加网络的非线性。 池化层(Pooling Layer): 池化层通常位于卷积层之后,用于降低特征图的维度(空间尺寸),减少计算量和参数数量,同时保持特征的空间层次结构。 常见的池化操作包括最大池化(Max Pooling)和平均池化(Average Pooling)。 全连接层(Fully Connected Layer): 在CNN的末端,通常会有几层全连接层(也称为密集层或线性层)。这些层中的每个神经元都与前一层的所有神经元连接。 全连接层通常用于对提取的特征进行分类或回归。 训练过程: CNN的训练过程与其他深度学习模型类似,通过反向传播算法和梯度下降(或其变种)来优化网络参数(如滤波器权重和偏置)。 训练数据通常被分为多个批次(mini-batches),并在每个批次上迭代更新网络参数。 应用: CNN在计算机视觉领域有着广泛的应用,包括图像分类、目标检测、图像分割、人脸识别等。 它们也已被扩展到处理其他类型的数据,如文本(通过卷积一维序列)和音频(通过卷积时间序列)。 随着深度学习技术的发展,卷积神经网络的结构和设计也在不断演变,出现了许多新的变体和改进,如残差网络(ResNet)、深度卷积生成对抗网络(DCGAN)等。

64,701

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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