华为笔试题 简答错误记录(字符串处理,好题!!!)


输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
文件路径为windows格式
如:E:\V1R2\product\fpgadrive.c 1325

输出描述:
将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1 
结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。
如果超过8条记录,则只输出前8条记录.
如果文件名的长度超过16个字符,则只输出后16个字符

输入例子1:
E:\V1R2\product\fpgadrive.c 1325

输出例子1:
fpgadrive.c 1325 1

链接:https://www.nowcoder.com/questionTerminal/67df1d7889cf4c529576383c2e647c48
来源:牛客网

分析:
比想象中要好做一些,直接按照要求编码即可。但是需要选好数据结构。说实话这道题的统计部分首先想到的方法是Python中的字典,与之类似的就是STL中的map。思路如下:
        1.将输入中目录部分去除,开始想使用类似Python中的split函数,结果STL中没有类似函数,我这里使用了string中的find+substr完成类似功能;
        2.将文件名字与行号组合作为键,输入中遍历组成map,使用map中的find,如果键值存在,键值+1;否则,键值为1;
        3.遍历map,将过长的文件名缩短至16个字符以内,并存入vector中备用。这里有人可能要问:能不能再输入时直接截取过长文件名。不是不可以,但是不建议,因为操作不当可能会引起重复记录。如若我们文件名最长只能有3位,再输入直接截取很容易出现a1.c与b1.c视为一个键的情况;
        4.排序,取前八个。由于如果一样多的话是安输入顺序来输出的,因此我能想到的最优排序方法是冒泡,而且是纯冒泡,不会出问题。为什么?我这里采用从下向上冒泡的方法,当大数字向上冒,遇到一样大的停下来,由于上面的比下面的先记录,因此数大小一样的情况下一定上面的是先记录的。
        有人可能会担心时间问题,毕竟冒泡的时间复杂度是O(n2)。但是由于我们只需要找出前八个最大的数字,因此是不需要进行全冒泡排序的,只需要给冒泡加以限制,时间就可因控制在8*n上,也就是说冒泡的时间复杂度在本程序中是O(n)!不比你快排快吗?
        由于其实现是利用红黑树完成的,所以数据记录部分的时间复杂度是O(nlgn);由于中途遍历一次,截取长名部分的时间复杂度是O(n);而冒泡时间复杂度是O(n)。因此程序的时间复杂度是nlgn + n + n = nlgn + 2n,即O(nlgn)。实际运行时间 3ms。代码如下:
 
code:
#include<bits/stdc++.h>
#include<string.h>
using namespace std;
#define max_v 105
#define INF 999999
#define me(a,x) memset(a,x,sizeof(a))
typedef long long LL;
map<string,int> mm;
vector<string> namelist;
vector<pair <string,int> > rs;

int main()
{
    string str1,str2;
    while(cin>>str1>>str2)
    {
        string str3=str1+" "+str2;
        int index=0;

        while((index=str3.find("\\"))!=-1)
        {
            str3=str3.substr(index+1);
        }

        if(mm.find(str3)==mm.end())
        {
            mm[str3]=1;
            namelist.push_back(str3);
        }
        else
        {
            mm[str3]++;
        }
    }
    for(int i=0; i<(int)mm.size(); i++)
    {
        int x=mm[namelist[i]];
        string name=namelist[i];
        if(name.find(" ")>16)
        {
            name=name.substr(name.find(" ")-16);
        }
        pair<string,int> temp(name,x);
        rs.push_back(temp);
    }

    for(int i=0; i<(int)rs.size()&&i<8; i++)
    {
        for(int j=rs.size()-1; j>i; j--)
        {
            if(rs[j].second>rs[j-1].second)
            {
                swap(rs[j],rs[j-1]);
            }
        }
    }

    for(int i=0; i<(int)rs.size()&&i<8; i++)
    {
        cout<<rs[i].first<<" "<<rs[i].second<<endl;
    }
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/yinbiao/p/10504654.html