华为2016校招 | 简单错误记录

题目:

开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)

3.输入的文件可能带路径,记录文件名称不能带路径

数据范围:输入错误记录数量满足 1≤n≤1000  ,每条记录的长度满足 1≤len≤50 

输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。

文件路径为windows格式

如:E:\V1R2\product\fpgadrive.c 1325

输出描述:

将所有的记录统计并将结果输出

格式:文件名 代码行数 数目,一个空格隔开,如: fpgadrive.c 1325 1

结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。

如果超过8条记录,则只输出前8条记录.

如果文件名的长度超过16个字符,则只输出后16个字符

输入例子:
E:\V1R2\product\fpgadrive.c 1325
输出例子:
fpgadrive.c 1325 1
#include <iostream>
#include <vector>
using namespace std;

//定义一个记录错误的结构
struct fileError {
    string fileName; //文件名
    int rowNum; //行数
    int count; //错误数
};
fileError fileArr[1000];
int length = 0; //记录数组长度
bool flag; //标记

//从字符串中取得文件名的方法
int getFileNum (string FileName) {
    int i = FileName.length() - 1;
    char temp = FileName[i]; //当前元素
    while(temp != '\\') {
        i--;
        temp = FileName[i];
    }
    return i;
}

//按照错误数大小排序的方法
void countSort(fileError f[]) {
    for (int i = length - 1; i > 0; i--) {
        for ( int j = 0; j < i; j++) {
            if (fileArr[j].count < fileArr[j + 1].count) {
                fileError temp = fileArr[j];
                fileArr[j] = fileArr[j + 1];
                fileArr[j+1] = temp;
            }
        }

    }
}

int main() {
    
    string name, fName; //输入文件地址,文件名
    int row, iName; //输入错误行数,从第i为开始截取文件名
    while (cin >> name >> row) { // 注意 while 处理多个 case
        iName = getFileNum(name) + 1;
        fName = name.substr(iName, name.length() - iName); 
        int i = 0;
        flag = true;
        //遍历vector,如果有相等字符串,且错误行数相同,则count++
        for(; i < length; i++) {
            if (fileArr[i].fileName == fName && fileArr[i].rowNum == row) {
                fileArr[i].count++;
                flag = false;
                break;
            }
        }
        //若没有相同错误,则pushback,令count为1
        if (flag) {
            fileArr[i].fileName = fName;
            fileArr[i].rowNum = row;
            fileArr[i].count = 1;
            length++;
        }
    }
        //输出
        countSort(fileArr);
        for ( int j = 0; j < 8; j++) { //最多记录8条错误记录
            if (fileArr[j].fileName.length() > 16) {
                cout << fileArr[j].fileName.substr(fileArr[j].fileName.length() - 16, 16) << " " << fileArr[j].rowNum << " " << fileArr[j].count << endl;
            } else {
                cout << fileArr[j].fileName << " " << fileArr[j].rowNum << " " << fileArr[j].count << endl;
            }
            
        }
    return 0;
}

知识点1

c++对字符串的操作

(9条消息) C++字符串常见操作函数最全总结_c++字符串操作函数_Cyril_KI的博客-CSDN博客

(9条消息) C++中的string类用法简介_c++ string_liitdar的博客-CSDN博客 

1. 构造函数:

string str; ——空串

string s(str);——将str复制到s

string s(num,c); ——生成由num个c字符构成的字符串

2. 插入函数:

有两种:push_back()和insert(),后者比较常用。
push_back():尾部插入一个字符,例如s.push_back(‘p’);
insert():例如s=“abcddss”,执行s.insert(s.begin(),‘i’)后在位置0前插入’i’变成"iabcddss"。
3. 遍历:

借助迭代器或者下标,下标比较常用,下标即字符串数组。

迭代器分两种:正向和反向。
正向:string::iterator it=s.begin();it!=s.end();it++;
反向:string::reverse_iterator it=s.rebegin();it!=s.rend();it++;
其中*it表示该位置的字符。

4. 查找:

1)查找一个字符串:s.find(ss),找到返回ss在s中的起始位置,否则返回-1;
2)从某一个位置开始查找某个字符:s.find(‘t’,6),从s的位置6开始查找字符’t’,找到则返回位置,否则返回-1;注意1)和2)都是返回第一次找到的位置;
3)从末尾开始查找某个字符:s.rfind(‘t’);
4)从某个位置开始查找第一个不属于s1的字符位置,例如s=“cdcdscds”,s1=“cdcdfff”,s.find_first_not_of(s1)=4,s的位置4字符不属于s1,类似的还有查找第一个属于s1的字符的位置,去掉not就好。

5. 排序:sort(s.bgein(),s.end());

6. 分割截取:

有两个函数:substr()与strtok()
s.substr(2,5)为s从2位置开始的5个字符组成的子串。
strtok()函数原型:char *strtok(char *s,const char *delim)
函数功能:分解字符串为一组字符串,s为要分解的字符串,delim为分隔字符串。
7. 删除:erase()函数,例如s=“12345678”,s.erase(s.begin()+3)后变为"1235678",即把位置3的字符删掉。

8. 替换:

repalce()函数:s.replace(pos,len,ss),将s从pos开始的len个字符替换成ss,
s.replace(pos,n1,n2,c),将s从pos开始的n1个字符替换成n2个字符c

9. 大小写转换:
tolower()和toupper()。循环遍历字符串的每一个位置s[i]=tolower(s[i]),大写转小写,或者s[i]=toupper(s[i]),小写转大写。
这里其实推荐用STL中的transform()函数,具体用法如下:
transform(s.begin(),s.end(),s.begin(),::tolower)大写转小写,小写转大写类似。

10. 比较函数:

string支持<,>,<=, >=, ==, != 等操作。
compare()函数专门用做string的比较函数,s.compare(ss)=0说明ss == s,返回1表明s>ss,返回-1表明s<ss。

11. 拼接函数:
c++的string支持直接相加,“cdd”+“sss”=“cddsss”

另外s.append(ss)表示在s最后加上ss,等同于s+=ss

12. 计算字符串长度:length( ),计算结果为字符串的实际长度

13. 判空:empty( )

14. string转换为char*

使用c_str( )方法

#include <string>
#include <iostream>
#include <stdio.h>
 
using namespace std;
 
int main()
{
    string strOutput = "Hello World";
 
    cout << "[cout] strOutput is: " << strOutput << endl;
 
    // string 转换为 char*
    const char* pszOutput = strOutput.c_str();
    
    printf("[printf] strOutput is: %s\n", pszOutput);
 
    return 0;
}
 

输出:

cout 可直接输出 string 类的对象的内容;
使用 c_str() 方法转换 string 类型到 char* 类型时,需要为char*添加 const 关键字;
printf() 函数不能直接打印 string 类的对象的内容,可以通过将 string 转换为 char* 类型,再使用 printf() 函数打印。
data( )方法和c_str( )方法:

两者都返回const char*类型,但在c++98版本中,data( ) 返回的字符串不以空字符结尾

15. char* char[ ] 转换为string

直接进行赋值操作,将 char*、char[] 的变量赋值给 string 对象即可。

实际上是将 char*、char[] 定义的字符串的首地址赋值给 string 对象了。

#include <string>
#include <iostream>
 
using namespace std;
 
int main()
{
    const char* pszName = "liitdar";
    char pszCamp[] = "alliance";
 
    string strName;
    string strCamp;
 
    strName = pszName;
    strCamp = pszCamp;
 
    cout << "strName is: " << strName << endl;
    cout << "strCamp is: " << strCamp << endl;
 
    return 0;
}

 

16. int类型转换为string类型

常用to_string( )来转换

#include <string>
#include <iostream>
#include <sstream>
 
using namespace std;
 
int main()
{
    // 方法1
    int nNum1 = 123;
    stringstream ss;
 
    ss << nNum1;
    string strTest1 = ss.str();
    cout << "strTest1 is: " << strTest1 << endl;
 
    /*
    string strTest2;
    strTest2 << ss;     // stringstream 未定义 << 操作符,故此句报错
    cout << "strTest2 is: " << strTest2 << endl;
    */
 
    string strTest3;
    ss >> strTest3;
    cout << "strTest3 is: " << strTest3 << endl;
 
    // 方法2
    int nNum2 = 456;
    string strTest4;
    strTest4 = to_string(nNum2);    // C++11 标准
    cout << "strTest4 is: " << strTest4 << endl;
 
    return 0;
}
 

 

知识点2

排序方法

//单独写一篇

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值