c++ demo: 单词转换
来源:互联网 发布:淘宝一元包邮的店 编辑:程序博客网 时间:2024/05/21 10:02
程序功能为:给定一个string,将它转换成为另一个string。程序的输入是两个文件,第一个文件保存一些规则,用来转换第二个文件的文本。每条规则由两部分组成:一个可能出现在输入文本中的单词和一个用来替换它的短语。表达的含义是,每当第一个单词出现在输入中时,就将它替换为对应的短语。第二个输入文件包含要转换的文本。
本人刚刚开始学习C++,从简单的程序入手,循序渐进。本程序来自primer c++中的。
比如:
第一个文件的内容:
u youa are
第二个文件的内容:
u a welcome!
程序输出为:
you are welcome!
源码:
Transformer.h 文件,定义了三个方法,其中word_transform方法将调用另外两个方法。
#include <iostream>#include <sstream>#include <c++/map>#include <c++/fstream>#ifndef TEXTTEST_TRANSFORMER_H#define TEXTTEST_TRANSFORMER_Husing namespace std;class Transformer {public: //转换的总体逻辑函数 void word_transform(ifstream &map_file, ifstream &input); //把转换规则文件中的内容保存到一个哈希表中,key为被转换的内容,value是转换的内容。作用:快速查找,查找的时间复杂度为0(1) map<string, string> buildMap(ifstream &map_file); //转换单词:如果在转换规则文件中存在该单词,就转换,如果没有,就返回原值。 const string& transform(const string &s, const map<string, string> &m);};#endif //TEXTTEST_TRANSFORMER_H
Transformer.cpp文件:实现头文件Transformer.h
//// Created by liangyh on 7/8/2017.//#include "Transformer.h"map<string, string> Transformer::buildMap(ifstream &map_file){ map<string, string> trans_map; string key; string value; while(map_file >> key && getline(map_file, value)){ if(value.size() > 1){ //使用substr的原因是去掉字符串前面的空格 trans_map[key] = value.substr(1); }else{ throw runtime_error("no rule for " + key); } } return trans_map;};void Transformer::word_transform(ifstream &map_file, ifstream &input){ auto trans_map = buildMap(map_file); string text; while(getline(input, text)){ istringstream stream(text); string word; bool firstWord = true; while(stream >> word){ if(firstWord){ firstWord = false; }else{ cout << " "; } cout << transform(word, trans_map); } cout << endl; }}//形参s使用了引用地址,避免在函数返回的时候进行不必要的复制。const string& Transformer::transform(const string &s, const map<string, string> &m){ auto map_it = m.find(s); if(map_it != m.cend()){ return map_it -> second; }else{ return s; }}
主函数:
#include <iostream>#include <c++/fstream>#include <c++/memory>#include "Transformer.h"using namespace std;int main0(int argc, char* argv[]) { string fileName1 = "C:\\Users\\liangyh\\Desktop\\TEMP\\t1.txt"; string fileName2 = "C:\\Users\\liangyh\\Desktop\\TEMP\\t2.txt"; ifstream inFile(fileName1.c_str()); ifstream inFile2(fileName2.c_str()); if(inFile.is_open() && inFile2.is_open()){ shared_ptr<Transformer> transformer(new Transformer());//智能指针 transformer->word_transform(inFile, inFile2); } return 0;}
思考和改进
1、在main函数中可以不使用智能指针的,程序将变成下面样子:
// shared_ptr<Transformer> transformer(new Transformer());// transformer->word_transform(inFile, inFile2); Transformer transformer; transformer.word_transform(inFile, inFile2);
使用智能指针的时候,Transformer对象保存在堆中,程序自动管理内存的回收工作。修改之后,对象将保存在栈中,main函数退出之后,内存自动释放。
2、c++中的函数形参是值传递,上面的程序使用了&的引用参数,也就是引用传参方式,避免了不必要的数据复制。这一点和Java有很大的区别。
3、上面的buildMap函数中的返回值是
map<string, string> trans_map;
注意,trans_map是一个局部变量,函数结束之后,这个局部变量应该会被回收,buildMap函数的调用者应该不会得到返回值的,可是,现实并不是这样子的:调用buildMap函数可以得到它的返回值。为什么呢?下面我们进行一个实验:
代码如下面所示:在方法中申明局部变量,并将其作为函数的返回值,同时打印函数内部该变量的地址和返回值的地址。
#include <iostream>#include <c++/fstream>#include <c++/memory>#include "Transformer.h"#include <c++/map>using namespace std;map<string, string> returnTest_map(){ map<string,string> result; result["1"] = "11"; result["2"] = "22"; cout << "map: " << &result << endl; return result;};int returnTest_int(){ int result = 2; cout <<"int: "<< &result << endl; return result;}long returnTest_long(){ long result = 3L; cout <<"long: "<< &result << endl; return result;}string returnTest_string(){ string result("hello"); cout <<"string: "<< &result << endl; return result;}//错误:返回局部变量的引用,函数结束之后,变量就被回收了。/*int& referenceTest(){ int result = 2 + 3; return result;}*/int main(int argc, char* argv[]) { map<string, string> result = returnTest_map(); cout <<"map: "<< &result << endl; int result2 = returnTest_int(); cout << "int: " << &result2 << endl; string result3 = returnTest_string(); cout << "string: " << &result3 << endl;// int result4 = referenceTest();// cout << result4 << endl; long result5 = returnTest_long(); cout << "long: " << &result5 << endl; return 0;}
结果:
map: 0x24fe10map: 0x24fe10int: 0x24fd9cint: 0x24fe0cstring: 0x24fde0string: 0x24fde0long: 0x24fd9clong: 0x24fddc
结果表明,map、string的变量前后是同一个变量,而int和long是不同的变量。这样的结果说明什么呢?1、对于int和long,函数在返回值的时候进行了拷贝操作。2、对于string和map,函数在返回值的时候没有进行内容的拷贝,这些内容不是保存在“栈”中,而是在“堆”中或者其他结构中。3、这个很可能涉及到c++编译器的优化问题,不同平台上面的编译器可能有所不同。
结束!
- c++ demo: 单词转换
- 单词转换
- C++primer 第十章 单词转换程序 运行不了解决办法
- c++primer关联容器中的“单词转换map程序”分析
- C++STL--map和set词频统计和单词转换
- 单词转换(stl map)
- C++ 单词转换例子
- 单词首字母转换大小写
- 字符串转换为单词,重复单词删除
- C/VC 进制数之间的转换 矩阵转置 单词计数
- C语言:输入英文句子,将所有单词首字符转换成大写后输出
- C++Primer第五版 练习11.38-2单词转换程序(解答)
- C++Primer第11章 一个单词转换的map【程序】
- 单词学习C
- c 语言背单词
- 用C统计单词
- 【C】单词统计
- C统计单词个数
- redux 在 React-Native 工作中的使用
- JZ2440 中断学习
- 删除字符串中出现次数最少的字符
- 笔记2
- 完全覆盖1-OJ
- c++ demo: 单词转换
- 《数据压缩》实验报告六·MPEG-1 Audio编码器
- linux内核分析——CFS(完全公平调度算法)
- 你以为的效率,可能只是焦虑
- 从编译过程看java的泛型
- Android仿百度贴吧客户端Loading小球
- hive实战之搜索热词
- python实现排序算法(上)
- LeetCode Weekly Contest 40(2)