question:
Given a string containing only ‘A’ - ‘Z’, we could encode it using the following method:
-
Each sub-string containing k same characters should be encoded to “kX” where “X” is the only character in this sub-string.
-
If the length of the sub-string is 1, ‘1’ should be ignored.
Input:
The first line contains an integer N (1 <= N <= 100) which indicates the number of test cases. The next N lines contain N strings. Each string consists of only ‘A’ - ‘Z’ and the length is less than 10000.
Output:
For each test case, output the encoded string in a line.
Sample Input:
2
ABC
ABBCCC
Sample Output:
ABC
A2B3C
本来不是什么难题。但是读题没读对。看着这个题给出的范例我最开始以为需要读入,计数并且排序,两个相关联的数据,很自然的就想到了map容器。
map容器处理关联问题
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
//读入字符?
//通过map建立key(字母)与value(次数)之间的映射
//接收输入->find()查找是否有该key->无则insert map/有则更改value
for(int i=0;i<n;i++){
map<char,int> m;
string s;
cin>>s;
char ch;
for(int i=0;i<s.length();i++)
{
ch=s[i];
if(m.find(ch)!=m.end()){//如果已经有了
m.find(ch)->second++;//那么次数加一//访问方式类似指针
}
else{
m.insert(pair<char,int>(ch,1));//初始插入value为1
}
}
for(auto x:m){
if(x.second!=1){cout<<x.second<<x.first;}
else{cout<<x.first;}
}
}
return 0;
}
想法单纯。结果第一次提交错了。崩溃。
然后想到了可能不是需要排序的,但是map又是自动排序的,就很为难。然后查用法,学到了可以用结构体/数组作为map的key或者value,但是key不能随意更改,所以肯定不能用来key来存次数。
所以尝试了用结构体作为map的value。有如下代码:
结构体做map的value
struct val{
int a;
int b;
bool operator < (const val &o) const{
return b<o.b;
}
};
int main()
{
int n;
scanf("%d",&n);
//读入字符?
//通过map建立key(字母)与value(次数)之间的映射
//接收输入->find()查找是否有该key->无则insert map/有则更改value
for(int i=0;i<n;i++){
// vector <char> vec;
// vector <int> c(100,0);
map<char,val> m;
val v;
string s;
cin>>s;
char ch;
for(int i=0;i<s.length();i++)
{
ch =s[i];
if(m.find(ch)!=m.end()){//如果已经有了
m.find(ch)->second.a++;//那么次数加一//访问方式类似指针
}
else{
v.b=i;
v.a=1;
m.insert(pair<char,val>(ch,v));//初始插入value为1
}
}
for(auto x:vec){
if(c[x]!=1){cout<<c[x]<<x;}
else{cout<<x;}
}
cout<<endl;
}
system("pause");
return 0;
}
值得注意的是,利用结构体作为map内元素进行赋值的时候,需要建立一个该结构体的变量用以接收值,再将结构体整体用pair/make_pair赋给map。
后来发现也不行。虽然我能储存了这个输入的顺序,但是输出的时候我需要两个循环遍历才能按照我b的大小顺序输出而且还得判断是否是重复的。
至此,心态崩溃60%.
为什么只是60%
因为我在搞结构体作为value的早就想到了更简单的方法:两个数组,用字符作为下标来计数共有多少个A,B···字符。
int main()
{
int n;
scanf("%d",&n);
//读入字符?
//通过map建立key(字母)与value(次数)之间的映射
//接收输入->find()查找是否有该key->无则insert map/有则更改value
for(int i=0;i<n;i++){
vector <char> vec;
vector <int> c(100,0);
// map<char,val> m;
// val v;
string s;
cin>>s;
char ch;
for(int i=0;i<s.length();i++)
{
ch =s[i];
if(find(vec.begin(),vec.end(),ch)!=vec.end()){c[ch]++;}
else{vec.push_back(ch);c[ch]++;}
}
for(auto x:vec){
if(c[x]!=1){cout<<c[x]<<x;}
else{cout<<x;}
}
cout<<endl;
}
system("pause");
return 0;
}
最后依然WA,心态崩溃99%了。
最后反复看题,反复看题,看着A2B3C这个数据,我醍醐灌顶,心中大叫一声马赛卡!!!。然后写出了AC代码如下:
AC代码
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
char temp;
string s;
cin>>s;
char pre=s[0];
for(int i=1,c=1;i<s.length();i++){
if(s[i]==pre){
pre=s[i];
c++;
if(i==s.length()-1){
cout<<c<<pre;
}
}
else{
if(c!=1){cout<<c<<pre;c=1;pre=s[i];}
else{cout<<pre;pre=s[i];}
if(i==s.length()-1){
cout<<pre;
}
}
}
cout<<endl;
}
return 0;
}
最后其实连容器都没用到。简单得我想自戕。
关于嵌套map
在最开始读错题意的时候,想到过用嵌套map,外层map用以根据输入顺序排序
如map<int,map<char,int>> m;
第一个int接收输入时i的大小,第二个int自然就是计数了。但是在测试输入为ABC的时候却错误输出了AABABC。其实就是根据第一个int顺序存的其实是当时的内层map,在只读入一个A的时候,内层map为map[‘A’]==1;然后输出就是只输出一个A。至于内层map其实还是在自动排序。