CCF 命令行选项( 满分代码 + 解题思路 + 技巧总结)2014-03-3

题目描述

在这里插入图片描述

解题思路

  • 题目中说明按照小写字母升序输出选项,所以可以将答案存储在string数组中,如果该字母为选项,则输出,若为带参选项,则将参数也输出,ans数组存储参数
  • 选项有两种,所以首先将第一行格式串读入,判定每个字母是否带参,用两个布尔数组来存储该字母是否带参
  • 为了方便字符串的存储,首先利用getline()读取一行的字符串内容
  • 利用stringstream将读取的一行字符串根据空格分层存储在vector数组
  • 然后根据读取到的内容进行判断,有三种情况:为无参选项(ans[i]随意存储一些内容),为有参选项(ans[i]存储数组的下一行),其他不合法则停止解析
  • 最后根据ans数组进行答案的输出,凡是命令行中出现的选项,其ans.size()不等于零,输出选项名称,若是带参选项,还要输出ans

代码实现1

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <sstream>

using namespace std;

const int N = 30;

bool op1[N], op2[N]; //op1存储无参数选项,op2存储有参数选项
int n;
string ans[N];

int main()
{
    string str;
    cin >> str; //读入所有的参数

    for (int i = 0; i < str.size(); i ++) //解析参数是否带参数
    {
        if (i + 1 < str.size() && str[i + 1] == ':') //如果下一位没有越界,并且下一位是冒号,则该位为带参选项
        {
            op2[str[i] - 'a'] = true; //表明str[i]为带参选项
            i ++; //跳过冒号
        }
        else
        {
            op1[str[i] - 'a'] = true;//表明str[i]为不带参选项
        }
    }

    cin >> n;
    getchar();//过滤回车

    for (int C = 1; C <= n; C ++)
    {
        printf("Case %d:", C);
        getline(cin, str); //读入整行需要用到getline,使用getline(如果上一个读入使用的是cin)需要将上一行的回车进行过滤
        string t;
        stringstream ssin(str);
        vector <string> ops;
        while(ssin >> t) ops.push_back(t);//将str按空格分层存储在数组

        for (int i = 0; i < 26; i ++) ans[i].clear();//将ans清空

        for (int i = 1; i < ops.size(); i ++) //第一个是名字,略过
        {
            if (ops[i][0] != '-' || ops[i][1] < 'a' || ops[i].size() != 2) break;
            int k = ops[i][1] - 'a';
            if(op1[k])
            {
                ans[k] = '*';
            }
            else if(op2[k] && i + 1 < ops.size())
            {
                ans[k] = ops[i + 1];
                i ++;
            }
            else break;
        }

        for (int i = 0; i < 26; i ++)
        {
            if(ans[i].size())
            {
                cout << " -" << char('a' + i);
                if(op2[i])
                {
                    cout << ' ' << ans[i];
                }
            }
        }
        cout << endl;
    }
    return 0;
}

代码实现2

#include <iostream>
#include <unordered_map>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

unordered_map <string, int> m; // <-a, 1/2>

vector <string> work(string str) //利用双指针将串根据空格进行分割
{
    vector <string> res;
    res.clear();

    for (int i = 0; i < str.size(); i ++)
    {
        int j = i; //i是字符
        string t = "";
        while (j < str.size() && str[j] != ' ') j ++; //j = str.size() 或 str[j] = ' '
        t = str.substr(i, j - i); 
        res.push_back(t);
        //cout << t << " ";
        i = j;
    }
    return res;
}

int main()
{
    string str;
    cin >> str;

    for (int i = 0; i < str.size(); i ++) //将格式串是否带参存储起来
    {
        string t = "-";
        t += str[i];
        if (str[i] == ':') continue;
        if ((i < str.size() - 1 && str[i + 1] != ':') || i == str.size() - 1)  m[t] = 1;
        else m[t] = 2;
        //cout << str[i] << " " << m[str[i]] << endl;
    }

    int n;
    cin >> n;

    getchar(); //读取回车
    for (int i = 1; i <= n; i ++)
    {
        str = "";
        getline(cin, str); //读取整一行字符串
        //cout << str << endl;

        vector <string> txt;
        txt.clear();
        txt = work(str);//将这行串根据空格进行拆分

        unordered_map <string, string> res; //<选项,参数》
        res.clear();

        for (int j = 1; j < txt.size(); j ++)
        {
            string x = txt[j];
            //if (x == "ls") continue; //这句话千万不能写,命令行的第一个单词可能并不是ls。。写了就0分。。
            if (m[x] == 1)
            {
                res[x] = "*";
            }
            else if (m[x] == 2 && j < txt.size() - 1)
            {
                res[x] = txt[ ++ j];
            }
            else break;
        }

        unordered_map <string, int> f;
        f.clear();

        sort(txt.begin(), txt.end());
        printf("Case %d:", i);
        for (auto x : txt)
        {
            if (res[x] != "" && f[x] == 0)
            {
                f[x] = 1;
                cout << " " << x;
                if (res[x] != "*") cout << " " << res[x];
            }
        }
        cout << endl;
    }
    return 0;
}


技巧总结

  • 模拟题主要要思考如何存储(存储解决问题百分之八十)
  • 字符串的存取方式的选择十分的重要
  • stringstreamvector等常用函数操作要运用熟练(二者结合使用可以是字符串根据空格分层存储
  • string数组从下标0开始存储
  • 清空string数组使用clear函数
  • 熟练运用字母下标映射的方法
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只可爱的小猴子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值