算法竞赛入门经典:第五章 基础题目选解 5.8 字母重排

/*
字母重排:
输入一个字典(用******结尾),然后再输入若干单词。每输入一个单词w,你都需要在字典中找出所有可以用w的字母重排后得到的单词,并按照字典顺序从小到大的
顺序在一行中输出(如果不存在,输出:( )。输入单词之间用空格或空行隔开,且所有输入单词都由不超过6个小写字母组成。注意,字典中的单词不一定按字典序排列
输入:
trap given score refund only trap work earn course pepper part
******
resco nfudre aptr sett oresuc
输出:
score
fefund
part tarp trap
:(
course

思路:
其实是输入的单词的全排列,n个单词有n!种组合,然后将n!个新单词在字典中去搜一把,凡是搜到的就输出字典中的单词
关键是确定全排列,例如resco,第一层从5个中选一个单词,第二层从剩余4个中选一个单词,关键是怎么选,可以用减枝标记,凡是选了的就不能再选
不需要搞全排列,可以将字典中单词排序,输入的单词也排序,两者比较相等,说明输入的单词已经在字典中了

考虑,有的单词输入都一样

1 <stdlib.h>中的排序函数,void qsort(const void* buffer,size_t num,size_t size,int(* compare)(const void*,const void*))
2 注意输出的顺序必须按照字典顺序,也就是说原来的输入字符串顺序也要先排 qsort(strDic,iCount,sizeof(strDic[0]),comp_str);
                                                                       qsort(strWord[j],strlen(strWord[j]),sizeof(char),comp_char);
  //比较的时候,字符串数组的个数为计数器的值,而每个字符数组的大小可用第一个字符数组大小表示
3 int comp_str(const void* _a,const void* _b)//注意函数指针必须是与sort函数中const void*形参相同
4 //iCount--;因为最后一次iCount累加没有加上
5 while(EOF != scanf("%s",strDic[iCount]))//scanf会过滤空格
  */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXSIZE 100

using namespace std;

//int comp_str(const char* _ptrStrA,const char* _ptrStrB)
int comp_str(const void* _a,const void* _b)//注意函数指针必须是与sort函数中const void*形参相同
{
	char* pA = (char*) _a;
	char* pB = (char*) _b;
	return strcmp(pA,pB);
}

//int comp_char(const char* _a,const char* _b)
int comp_char(const void* _a,const void* _b)
{
	char* a = (char*)_a;
	char* b = (char*)_b;
	return(*a - *b);
}

void input()
{
	char strDic[MAXSIZE][7];//原有字典
	char str[MAXSIZE][7];//辅助数组,存放已经排序过的字典
	char strWord[MAXSIZE][7];
	int iCount = 0;
	while(EOF != scanf("%s",strDic[iCount]))//scanf会过滤空格
	{
		if(!strcmp("******", strDic[iCount]))//字符数组的比较不能用"******" == strDic[iCount]直接比较,必须用strcmp
		{
			break;
		}
		//对输入的单词排序
		//strcpy(str[iCount],strDic[iCount]);
		//sort(str[iCount],str[iCount] + strlen(str[iCount]));
		//qsort(str[iCount],strlen(str[iCount]),sizeof(char),comp_char);
		iCount++;
	}
	//单词组顺序进行排序
	//iCount--;因为最后一次iCount累加没有加上
	//sort(strDic,strDic + iCount);
	qsort(strDic,iCount,sizeof(strDic[0]),comp_str);//比较的时候,字符串数组的个数为计数器的值,而每个字符数组的大小可用第一个字符数组大小表示
	//拷贝后,再对每个单词进行排序
	for(int q = 0 ; q < iCount ; q++)
	{
		strcpy(str[q],strDic[q]);
		sort(str[q],str[q] + strlen(str[q]));
	}
	//接下来对每个输入的单词进行判断
	int j = 0;
	while(EOF != scanf("%s",strWord[j]))
	{
		//sort(strWord[j],strWord[j] + strlen(strWord[j]));
		qsort(strWord[j],strlen(strWord[j]),sizeof(char),comp_char);
		j++;
	}
	for(int m = 0; m < j;m++)
	{
		bool isFind = false;
		for(int k = 0; k < iCount;k++)
		{
			if(!strcmp(strWord[m],str[k]))
			{
				printf("%s ",strDic[k]);
				isFind = true;
				//break;//因为还有单词会相同
			}
		}
		if(!isFind)
		{
			printf("%s",":(");
		}
		printf("\n");
	}
}

int main(int argc,char* argv[])
{
	input();
	system("pause");
	return 0;
}

你可能感兴趣的:(算法竞赛入门)