题目描述
小红又给小明出难题了,这次的问题是给小明一些非负整数,让他按照一定的规则编程改写这些整数,规则如下:
如果某个正整数中有n个相同的数字x连续出现,那么将它们改写成“nx”的形式;
对于单独出现的数字x,将其改写成“1x”的形式。
例如,122344111应该改写为1122132431。
由于小明的编码能力太弱,所以请你帮他编程解决这个问题
输入
输入的第一行是一个正整数n(n<=1000),表示测试数据的组数。
接下来n行,每行输入一个要改写的非负整数,每个整数的位数不超过1000。
输出
对于每组输入,输出改写后的形式。
样例输入
3
122344111
1111111111
12345
样例输出
1122132431
101
1112131415
分析:
作者目前大一,成绩一般,水平有限,采取的都是自己第一时间想到的方法,可能不够优化,有些繁琐,我一直在努力。下面进入正文:
由于输入有最多1000组数据且数据的位数最多位1000,故定义一个二维数组s[1000][1000] 而我一般在实际的做OJ题目的时候都会习惯性的多定义5个单位长度(s[1005][1005])以字符的形式储存,一行代表一个整数,共n行。
主函数完成n个数的输入,定义函数count_printf完成数据发处理输出。
子函数中的处理思路是:定义一个字符数组s[2005]存放每组数据处理后的结果,对于每次出现连续的情况,例如 222 3333结果为3243,先统计数字出现的次数3,再把次数3和该数字2以字符的形式(32)储存到数组s中,一步步实现。具体见下方代码,其中如果出现次数达到10次及以上的处理方式不一样,要分开讨论。代码如下:
#include <stdio.h>
char s[1005][1005];
int main()
{
int i,j,n;
void count_printf(int i,int n); //处理函数
scanf("%d",&n); //测试组数
getchar(); //清空键盘的缓存区'\n'
for(i=0;i<n;i++) //循环n次,调用n次count_printf
{
for(j=0;s[i][j-1]!='\n';j++)
{
s[i][j]=getchar();
}
s[i][j-1]='\0'; //其实我觉得这步好像不需要
count_printf(i,j-1); //i表示二维数组的行,j-1表示的是输入的数字的位数
}
return 0;
}
void count_printf(int i,int n)
{
int j, t, k=0, num=0, number=0, count=1;
char a[2005]; //字符数组存放处理结果,假设全部都是不连续的总共也就需要2000个字符,所以我定义了2005长度
for(j=0;j<n;j++)
{
if(s[i][j]==s[i][j+1])count++; //若前一个与后一个相同count加1,count的初值为1,当前后不等时进行存储到字符数组a中
else //此时分两种情况处理,1种是数字连续出现次数不超过9,这种直接转字符形式储存
{
if(count<10)a[k]=count+'0'; //转字符储存
else //超过9的情况,由于最高位位1000,故连续次数最高四位数,依次求出千、百、十、个位的数字,转为字符储存
{
t=count/1000;
if(t!=0)a[k++]=t+'0',number++; //number用于计数,统计数组a的长度,在最后输出时需要
count=count%1000;
t=count/100;
if(t!=0)a[k++]=t+'0',number++; //注意这里k自增
count=count%100;
t=count/10;
if(t!=0)a[k++]=t+'0',number++; //注意这里k自增
count=count%10;
a[k]=count+'0'; //注意这里k没有自增
}
a[k+1]=s[i][j]; //注意这里k没有自增
k=k+2; //两次k没有自增,加2把k移到还没储存的位置
num=num+number+2; //num用于计算a数组长度
number=0; //初始化number和count
count=1;
}
}
for(j=0;j<num;j++) //输出结果
printf("%c",a[j]);
printf("\n");
}
2018已经接近尾声,我大一,第一次写博客,代码也不够好,算法不够优化,都是暴力做题的。
谢谢你们花时间看了。
(代码冗长)说实话换作我也不太愿意看,我一直在努力。