【题目】
给定两个字符串str1和str2,如果str1和str2中出现的字符种类一样且每种字符出现的次数也一样,那么str1和str2互为变形词。请实现函数判断两个字符串是否互为变形词。
【举例】
str1="123",str2="231",返回true。
str1="123",str2="2331",返回false。
【实现】
#include <iostream>
#include <stdlib.h>
#include <string>
#include <map>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string str1, str2;
getline(cin,str1);
getline(cin,str2);
if (str1== ""|| str2 == ""||str1.size()!=str2.size())
{
cout << "false";
return 0;
}
map<int, int> charCount;
int length = 0;
while (str1[length] != '\0')
{
charCount[str1[length]]++;
length++;
}
length = 0;
while (str2[length] != '\0')
{
if (--charCount[str2[length]] < 0)
{
cout << "false";
return 0;
}
length++;
}
cout << "true";
return 0;
}
【知识点】
1、程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据。正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入。
#include <iostream>
using namespace std;
int main()
{
char str[8];
cin.getline(str, 5);
cout<<str<<endl;
cin.getline(str, 5);
cout<<str<<endl;
return 0;
}
测试:
abcdefgh (回车)
abcd (输出)
【分析】之所以第一次输入完后直接程序就结束了,而不是进行第二次输入,是因为第一次多输入的数据还残留在缓存区中,第二次输入就直接从缓存区中提取而不会请求键盘输入。
2、C++中常用的输入语句主要有cin、cin.get()、cin.getline()、getline()等,下面总结一下他们各自的用法:
①cin:该操作符是根据后面变量的类型读取数据;
输入结束的条件为遇到Enter、Space、Tab键;
对结束符的处理 :丢弃缓冲区中使得输入结束的结束符(Enter、Space、Tab)。
②cin.get():可以用来接收一个字符,也可以用来接收一个字符串(cin.get(字符数组名,接收字符数目))
输入结束条件:Enter键。
对结束符处理:不丢弃缓冲区中的Enter。
③cin.getline():cin.getline(数组名,长度,结束符) 大体与 cin.get(数组名,长度,结束符)类似。
区别:cin.get()当输入的字符串超长时,不会引起cin函数的错误,后面的cin操作会继续执行, 只是直接从缓冲区中取数据。但是 cin.getline()当输入超长时,会引起cin函数的错误,后面的 cin操作将不再执行。
④getline():接受一个字符串,可以接收空格并输出,需包含“#include<string>”,和cin.getline()类似,但是 cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数。
读入字符串用getline,读入字符数组使用cin.get()或者cin.getline(),这两个都是安全的函数。
3、在实现时需要时刻记着检查程序的输入,比如这里检查输入的字符串是否为空(即需要检查一些边界条件)。
4、本题的巧妙之处在于使用了map这个数据结构,大大简化了题目的难度,可见有时选对的数据结构进行解题往往可以达到事半功倍的效果。