zoukankan      html  css  js  c++  java
  • 华为笔试题 简答错误记录(字符串处理,好题!!!)


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

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

    输入例子1:
    E:V1R2productfpgadrive.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;
    }
    
    
  • 相关阅读:
    堆和栈的区别
    熟悉熟悉常用的几个算法用JS的实现
    JS设置CSS样式的几种方式
    javascript的基本语法、数据结构
    DOM的概念及子节点类型
    三列自适应布局
    Javascript中括号“[]”的多义性
    Javascript中大括号“{}”的多义性
    Javascript小括号“()”的多义性
    JavaScript 开发者经常忽略或误用的七个基础知识点
  • 原文地址:https://www.cnblogs.com/yinbiao/p/10504654.html
Copyright © 2011-2022 走看看