POJ1318_word amalgamation

本文介绍了一种基于字典匹配的谜语解码算法,通过排序和比较来寻找谜语的谜底。文章详细解释了算法流程,包括字典排序、谜语字母排序等关键步骤,并提供了完整的C语言代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:
先给出若干个单词,这个单词集合作为一个字典。然后会再给出一系列单词序列,这个单词集合作为谜语集合,每个谜语都是一个单词。
将谜语看成一个个字母组成的序列,将这些字母序列进行排列组合,如果某一个组合在字典中,那这个组合就可以看做是这个谜语的谜底。

解码例子:
假设字典为{tarptrap, given,  hello}
谜语为{aptrvgineasd}
tarptrapaptr的谜底, givenvgine的谜底。asd没有谜底
NOTE: 一个谜语可能对应多个谜底,也可能没有谜底与之对应。

输入格式描述:
一个字典,至少包含一个单词,最多100个单词,每个单词一行。
一行XXXXXX,它表示字典输入结束
一个或多个谜语,你需要找出它们的谜底。每个谜语各占一行,

    一个谜语就是一个单词。

一行XXXXXX,表示谜语输入结束
所有的字典和谜语中的单词都是由小写字母组成,每个单词的长度至少为1,最大为6
NOTE:XXXXXX6个大写的X字母。字典中的单词不一定是按字母序进行输入的,同时字典中的单词不会重复

输出描述:
对于每个谜语,按照字母序输出所有的谜底,输出的每个谜底各占一行,如果一个谜语找不到谜底,输出‘NOT A VALID WORD’
如果一个谜语对应着多个谜底,则按照字典序(不是该题中的字典序,以字符串从小到大的顺序输出谜底)输出每个谜底
输出完一个谜语的所有谜底之后,输出‘******’,将不同的谜语的谜底分割开

实现效果:

知识要点:字符串的基本操作

解题思路:最普遍的一种解题思路,构建二维数组存放输入的字典集,构建一维数组存放输入的谜语。由于题目要求存在多个谜底时按照字符串从大到小的顺序输出,因此需要先对字典集按照首字母进行排序,并且备份到另一二维数组中。然后对于字典集中的所有单词以及输入的谜语按照字母从小到大的顺序进行排序,再将谜语和排好序的字典集对比,若有相同的则输出谜底。

解题过程中的实用函数:strcmp函数 判断两个字符串是否相同;strcpy函数 将一个数组中的数据复制到另一个数组中;memset函数 用于字符串的初始化。
代码实现:
#include <stdio.h>
#include <string.h>

char in[100][20], dic[100][20];//分别用于存放输入的字典集以及备份未排序的字典集
char mi[20];//用于存放输入的谜语
int num;//记录输入的字典单词数量

void input()
{
	int i;
	for (i = 0; i < 100; i++)
	{
		gets_s(in[i]);
		if (strcmp(in[i], "XXXXXX") == 0)//当输入XXXXXX时,字典集输入结束
		{
			num = i;
			break;
		}
	}
}

void sort(char *dic)//对字典集以及迷语中的所有单词按照字母从小到大的顺序排列
{
	int len = strlen(dic);
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = i + 1; j < len; j++)
		{
			if (dic[i] > dic[j])
			{
				char temp = dic[i];
				dic[i] = dic[j];
				dic[j] = temp;
			}
		}
	}
}

int main()
{
	input();//输入字典集
	for (int i = 0; i < num - 1; i++)//将字典集按照首字母从小到大排序
	{
		for (int j = i + 1; j < num; j++)
		{
			if (strcmp(in[i], in[j]) == 1)
			{
				char re[20];
				strcpy_s(re, in[i]);
				strcpy_s(in[i], in[j]);
				strcpy_s(in[j], re);
			}
		}
	}

	for (int i = 0; i < num; i++)
		strcpy_s(dic[i], in[i]);//用另一二维数组备份原字典集
	for (int i = 0; i < num; i++)
		sort(in[i]);//将原字典集的每一个单词按照字母顺序重新排列

	while (1)
	{
		memset(mi, '\0', 20);//初始化谜语数组
		gets_s(mi);
		if (strcmp(mi, "XXXXXX") == 0)
			return 0;//当输入xxxxxx时,程序结束
		bool flag = true;
		sort(mi);

		for (int i = 0; i < num ; i++)
		{
			if (strcmp(mi, in[i]) == 0)
			{
				flag = false;
				puts(dic[i]);
			}
		}
		if (flag)//没有符合条件的谜底
			printf_s("NOT A VALID WORD\n");
		printf_s("******\n");
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值