第一讲先从一个实例开始——我们需要完成一个遍历文件并统计单词出现次数的任务。分解功能:首先,按行读取文件并舍弃可能的空行。其次,将每一行都按照空格划分单词。因为可能存在标点符号,我们还需要将标点符号都删除。最后把行首或专有名词中出现的大写字母统一转换。最后将所有获取的字母放到一个关联容器中(map<string, int>)统计出现的次数。

一、从文件中读取并按行分割

(1)标准方法与参数

std::getline(basic_istream<charT,traits>& is, basic_string<charT,traits,Alloc>& str, charT delim)

参数1.输入流

参数2.接受字符串

*参数3.分割符

(2)代码实例

// 文件输入流
ifstream ifs("hello.txt");
// 行字符串向量类型
vector<string> paragraphs; string temp;
// 遍历全文
while(std::getline(ifs, temp) {
paragraphs.push_back(temp);
}

二、以空格分隔字符串

(1)标准方法与参数

find_first_of (const basic_string& str, size_type pos = 0) const

参数1.字符串

*参数2.起始位置

substr (size_type pos = 0, size_type len = npos) const

*参数1.起始位置

*参数2.长度

(2)代码实例

const string key = " "; // 空格
vector<string> words; // 单词集合
string line; // 行 string::size_type pos = , prev = ; // 系统相关变量。记录当前查找到空格的位置和前一个单词的起始位置。 while((pos = line.find_first_of(key, line)) != string::npos) {
words.push_back(line.substr(pos, pos-prev));
prev = ++pos;
}

三、大小写转换

(1)标准方法与参数

int tolower (int c)

参数.大写字母

返回.小写字母

(2)代码实例

string caps("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); // 大写字母集合
string::size_type pos = ;
string word;
while((pos = word.find_first_of(pos, caps)) != string::npos) {
w[pos] = tolower(w[pos]); // 用小写字母替换对应的大写
}

四、计数

(1)标准方法与参数

pair<iterator,bool> insert (const value_type& val)

参数1.value_type<K, V>(k, v) 插入值

*向map对象插入新值可以使用索引的方式,如map<string, int> m; m["hello"] = 37; 但是这会发生以下的事情,从而导致严重的性能损失:

  1. 一个未命名的临时string 对象被构造并传递给与map 类相关联的下标操作符这个对象用“hello”初始化;

  2. 一个新的键/值对被插入到m中当然键是一个“hello”对象持有Anna但是值是0,而不是37;

  3. 插入完成接着值被赋为37;

所以推荐做法是使用insert方法。

(2)代码实例

map<string, int> m;
m.insert(map<string, int>::value_type("hello", ));

五、完整代码

.h

#ifndef TEXTUTILS_H
#define TEXTUTILS_H
#include <string> // string getline
#include <vector> // vector
#include <fstream> // ifstream
#include <iostream> // cout endl
#include <stdlib.h> // exit
#include <locale> // tolower
#include <map> // map using namespace std; class TextUtils
{
public:
TextUtils();
virtual ~TextUtils();
public:
// 静态方法:单词统计
static map<string, int>* wordStatistics(string filename, string filter = ",.:;?\"!");
private:
// 按照段落划分
void paragraphs(ifstream& ifs, vector<string>* p);
// 获取单词集合
void words(vector<string>* p, vector<string>* w, const string filter = ",.:;?\"!");
// 小写替换
void lower(vector<string>* w);
// 计数
void counter(map<string, int> *out, vector<string> *in);
}; #endif // TEXTUTILS_H

.cpp

#include "TextUtils.h"

map<string, int>* TextUtils::wordStatistics(string filename, string filter) {
TextUtils utils;
ifstream fin(filename.c_str(), ios::in);
// 判断文件是否存在
if(!fin) {
exit(-);
}
// 声明段落容器
vector<string> p;
utils.paragraphs(fin, &p);
// 声明字母容器
vector<string> w;
utils.words(&p, &w);
// 大小写转换
utils.lower(&w);
// 声明返回指针
map<string, int> *m = new map<string, int>;
utils.counter(m, &w); return m;
} void TextUtils::paragraphs(ifstream& ifs, vector<string>* p) {
string temp;
while(getline(ifs, temp, '/n')) {
if(temp.size()) p->push_back(temp);
}
} void TextUtils::words(vector<string>* p, vector<string>* w, const string filter) {
for(vector<string>::iterator it=p->begin(); it != p->end(); ++it) {
string paragraph = *it;
string::size_type pos = , prev_pos = ;
while((pos = paragraph.find_first_of(' ', pos)) != string::npos) {
w->push_back(paragraph.substr(prev_pos, pos-prev_pos));
prev_pos = ++pos;
}
w->push_back(paragraph.substr(prev_pos, pos-prev_pos));
} // 遍历字母中的标点,删除
for(vector<string>::iterator it = w->begin(); it != w->end(); ++it) {
string::size_type pos = ;
while((pos = (*it).find_first_of(filter, pos)) != string::npos) {
(*it).erase(pos, );
}
}
} void TextUtils::lower(vector<string>* w) {
string caps("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
for(vector<string>::iterator it = w->begin(); it != w->end(); ++it) {
string::size_type pos = ;
while((pos = (*it).find_first_of(caps, pos)) != string::npos) {
(*it)[pos] = tolower((*it)[pos]);
}
}
} void TextUtils::counter(map<string, int> *out, vector<string> *in) {
for(vector<string>::iterator it = in->begin(); it != in->end(); ++it) {
// 如果单词不存在,则在容器中插入新值。否则做自增操作
if(!out->count(*it)) {
out->insert(map<string, int>::value_type(*it, ));
} else {
++((*out)[*it]); // ++i的效率高于i++
}
}
}

总结:通过一个不难么简单例子作为C++学习的启蒙或许对有些初学者来说不那么友好。不过,我之所谓选择已这个例子因为它恰恰展现了这门语言的特点:高效。

C++学习笔记(一)——一个字符串分割和统计的工具(TextUtils)的更多相关文章

  1. python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...

  2. 【python学习笔记】3.字符串使用

    [python学习笔记]3.字符串使用 字符串是一种序列,素有标准的序列操作对字符串用样适用,字符串是不可以改变 格式化操作符,%,左侧是格式化字符串,右侧是被格式的值,可以是一个值.元组.字典 数值 ...

  3. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

  4. matlab学习笔记10_5 通用字符串操作和比较函数

    一起来学matlab-matlab学习笔记10 10_5 通用字符串操作和比较函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用>张 ...

  5. python学习笔记(二)、字符串操作

    该一系列python学习笔记都是根据<Python基础教程(第3版)>内容所记录整理的 1.字符串基本操作 所有标准序列操作(索引.切片.乘法.成员资格检查.长度.最小值和最大值)都适用于 ...

  6. 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端

    接上文 多线程编程学习笔记——使用异步IO 二.   编写一个异步的HTTP服务器和客户端 本节展示了如何编写一个简单的异步HTTP服务器. 1.程序代码如下. using System; using ...

  7. python3学习笔记——数字、字符串、列表、字典、元组

    什么是python解释器? python代码在解释器中运行.解释器是代码与计算机硬件之间的软件逻辑层. python的执行过程                                      ...

  8. c语言学习笔记 - 指针和字符串

    前面学习了字符串是一种字符数组,又知道了指针变量和数组的关系,这里来看一下指针和字符串的关系. #include <stdio.h> int main(void){ char str = ...

  9. python学习笔记20(字符串格式化)

    Python中内置有对字符串进行格式化的操作% 模板 格式化字符串时,Python使用一个字符串作为模板.模板中有格式符,这些格式符为真实值预留位置,并说明真实数值应该呈现的格式.Python用一个t ...

随机推荐

  1. JVM、Java编译器和Java解释器

    作用: JVM:JVM有自己完善的硬件架构,如处理器.堆栈(Stack).寄存器等,还具有相应的指令系统(字节码就是一种指令格式).JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需要生成 ...

  2. php分层

    表示层         UI      主要表示WEB方式,也可以表示成WINFORM方式.如果逻辑层相当强大和完善,无论表现层如何定义和更改,逻辑层都能完善地提供服务. 业务逻辑层  BLL     ...

  3. c# 日期函数[string.Format----GetDateTimeFormats]格式

    DateTime dt = DateTime.Now;Label1.Text = dt.ToString();//2005-11-5 13:21:25Label2.Text = dt.ToFileTi ...

  4. 登录使用inode的校园网用到的url

    无需使用inode客户端,直接访问下面的url,然后输入账号密码即可. 第一次访问这个url的时候可能会提示下载inode客户端,再访问一次即可. url1:http://172.20.1.1/por ...

  5. sql distinct去除重复

    distinct select  distinct * from  table1 或者用 group  by

  6. CAScrollLayer

    CAScrollLayer 对于一个未转换的图层,它的bounds和它的frame是一样的,frame属性是由bounds属性自动计算而出的,所以更改任意一个值都会更新其他值. 但是如果你只想显示一个 ...

  7. ADO.NET知识学习总结

      1. 概述 使用的命名空间: System.Data.SqlClient 连接字符串    服务器/数据库实例+数据库名称+安全信息+用户名+密码  可参考http://www.connectio ...

  8. quartz-job实现实时或定时发送短信任务

    存放调度器(Job 和 Trigger)信息的xml配置文件: 这是某个指定的要实现的定时任务: <!-- 每天给项目经理发送短信避免短信服务挂了 定时每天08:30执行--> <j ...

  9. 浏览器内核、排版引擎、js引擎

    [定义] 浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“渲染引擎”,不过我们一般习惯将之称为“浏览器内核”.负责对网页语法的解释(如标准通用标记语 言下的一个应用HT ...

  10. 20145332卢鑫 WEB基础

    20145332卢鑫 WEB基础 实验过程 1.环境配置 2.简单的网页编写 3.javascript相关 1.相关概念:JavaScript是一种广泛用于客户端Web开发的脚本语言,常用来给HTML ...