问题描述 Anagrams指的是具有如下特性的两个单词:在这两个单词当中,每一个英文字母(不区分大小写)所出现的次数都是相同的。例如,“Unclear”和“Nuclear”、“Rimon”和“MinOR”都是Anagrams。编写一个程序,输入两个单词,然后判断一下,这两个单词是否是Anagrams。每一个单词的长度不会超过80个字符,而且是大小写无关的。 输入格式:输入有两行,分别为两个单词。 输出格式:输出只有一个字母Y或N,分别表示Yes和No。 输入输出样例 样例输入 Unclear Nuclear 样例输出 Y
两个思路, 思路一:比较麻烦,算法复杂度较大,不进行排序,直接就进行比较, 首先一种情况,如果两个字符串的长度不一样,就没有比较的必要了。 比较的时候,设计两个for循环,上面的字符串的一个元素遍历下面的,看是否有相同的(不区分大小写),但是仅仅是这样,还不够,因为范例是可以很轻松的举出来,比如hehe,heee,这两个,上下的字母种类相同,但是个数不同,但是并不能检测出来,所以要再加一个条件,设置一个标记数组,之前的有被遍历的且成功的,都会把下标记录下来,存进去,所以后来再有相同的时候,只需要判断下标就好了
代码:
#include<iostream> #include<string> using namespace std; int biao[100];//标记位 int length=0; bool isbelong(int n) { for(int i=0;i<length;i++) { if(n==biao[i]) { return 1; } } return 0; } int main() { string a; string b; cin>>a>>b; int len1=a.length(); int len2=b.length(); if(len1!=len2) { cout<<"N"; } for(int i=0;i<len1;i++)//数组的默认值为零,会影响判断,所以先给个比较大的数 { biao[i]=100; } for(int i=0;i<len1;i++) { for(int j=0;j<len2;j++) { if(((a[i]==(b[j]-32))||(a[i]==(b[j]+32))||a[i]==b[j])&&(!isbelong(j))) { biao[length]=j; length++; break; } else { if(j==len2-1) { cout<<"N"; return 0; } else{ continue; } } } } cout<<"Y"; return 0; }这种算法确实是对的,但是不好,效率不高且不容易理解
所以,上干货,先把两个字符串都统一转化成小写或者大写,然后分别对他们进行排序,这样之后,他们应该是完全一样的如果符合要求的话,一一比较就好了
#include<iostream> #include<string> using namespace std; void transB2s(string &s) //对字母的大小写进行转换,方便排序 { for(int i=0;i<s.length();i++) { if(s[i]<97) { s[i]=s[i]+32; } } } void sort(string &s) { int i,j,k,t; for(int i=0;i<s.length()-1;i++) { k=i; for(j=i+1;j<s.length();j++) { if(s[k]>s[j]) k=j; } t=s[i]; s[i]=s[k]; s[k]=t; } } int main() { string a; string b; cin>>a>>b; int len1=a.length(); int len2=b.length(); if(len1!=len2) { cout<<"N"; } transB2s(a); transB2s(b); // cout<<a<<endl<<b; sort(a); sort(b); // cout<<a<<endl<<b; for(int i=0;i<len1;i++) { if(a[i]!=b[i]) { cout<<"N"; return 0; } } cout<<"Y"; return 0; }