VJ STL Encoding(解题过程+学到的新知识:结构体作map key,value,构造cmp+嵌套map的一些误区)

question:

Given a string containing only ‘A’ - ‘Z’, we could encode it using the following method:

  1. Each sub-string containing k same characters should be encoded to “kX” where “X” is the only character in this sub-string.

  2. 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其实还是在自动排序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值