算法竞赛入门经典 第四章 学习笔记 2

算法竞赛入门经典 第四章 学习笔记 2

把函数作为函数的参数

例题4-1 古老的密码(Ancient Cipher, NEERC 2004, UVa1339)

给定两个长度相同且不超过100的字符串,判断是否能把其中一个字符串的各个字母重 排,然后对26个字母做一个一一映射,使得两个字符串相同。例如,JWPUDJSTVP重排后可 以得到WJDUPSJPVT,然后把每个字母映射到它前一个字母(B->A, C->B, …, Z->Y, A- >Z),得到VICTORIOUS。输入两个字符串,输出YES或者NO
题目分析:
因为字母可以重排,每个字母的位置并不重要,重要的是每个字母出现的次数
①统计两个字符串每个字母出现的次数,得到两个数组cnt1[26],cnt2[26]
②之后我们排序下,排序之后结果相同,说明我们输入的两个字符串就可以通过重排一一映射变得相同了所以本道题的核心在于排序
C语言的stdlib.h中有一个叫qsort的库函数,实现了著名的快速排序算法。了解

void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
/*前3个参数不难理解,分别是待排序的数组起始地址、元素个数和每个元素的大小。最 后一个参数比较特别,是一个指向函数的指针,该函数应当具有这样的形式:int cmp(const void *, const void *) { … }
*/

指向常数的“万能”的指针:const void *,它可以通过强制类型转化变成 任意类型的指针

#include<iostream>
#include<stdlib.h>
#include<cstring>
using namespace std;
int cmp(const void* a,const void *b)
{
	return *(int*)a-*(int*)b;
	//(int*)a:类型转化       变成int类型的指针,然后*这个指针,得到这个变量 
}
int main()
{
	char s1[105],s2[105];
	while(cin>>s1>>s2)
	{
		int cnt1[26]={0},cnt2={0};
		int len=strlen(s1),flag=1;
		for(int i=0;i<len;i++)
		{
			cnt1[s1[i] - 'A']++, cnt2[s2[i] - 'A']++;
		}
		qsort(cnt1, 26, sizeof(int), cmp);//void qsort(void *base, sieze_t num, size_t size, int(*comparator)(const void* ,const void*) );
		qsort(cnt2, 26, sizeof(int), cmp);//             数组名字    数组大小     单位长度       比较函数
		for (int i = 0; i < 26; i++)
			if (cnt1[i] != cnt2[i]) { flag = 0; break; }
		if (flag)printf("YES\n");
		else printf("NO\n");
	} 
	return 0;
} 

猜你喜欢

转载自www.cnblogs.com/serendipity-my/p/12636170.html