UVA - 508 Morse Mismatches

Morse Mismatches

Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

Submit Status

Description

Samuel F. B. Morse is best known for the coding scheme that carries his name. Morse code is still used in international radio communication. The coding of text using Morse code is straightforward. Each character (case is insignificant)
is translated to a predefined sequence of dits and dahs (the elements of Morse code). Dits are represented as periods (``.‘‘) and dahs are represented as hyphens or minus signs (``-‘‘).
Each element is transmitted by sending a signal for some period of time. A dit is rather short, and a dah is, in perfectly formed code, three times as long as a dit. A short silent space appears between elements, with a longer space between characters. A still
longer space separates words. This dependence on the spacing and timing of elements means that Morse code operators sometimes do not send perfect code. This results in difficulties for the receiving operator, but frequently the message can be decoded depending
on context.

In this problem we consider reception of words in Morse code without spacing between letters. Without the spacing, it is possible for multiple words to be coded the same. For example, if the message ``dit dit dit‘‘ were received, it could be interpreted as
``EEE‘‘, ``EI‘‘, ``IE‘‘ or ``S‘‘ based on the coding scheme shown in the sample input. To decide between these multiple interpretations, we assume a particular context by expecting each received word to appear in a dictionary.

For this problem your program will read a table giving the encoding of letters and digits into Morse code, a list of expected words (context), and a sequence of words encoded in Morse code (morse). These morse words may be flawed. For each morse word,
your program is to determine the matching word from context, if any. If multiple words from context match morse, or if no word matches perfectly, your program will display the best
matching word and a mismatch indicator.

If a single word from context matches morse perfectly, it will be displayed on a single line, by itself. If multiple context words exist for
a given morse, the first matching word will be displayed followed by an exclamation point (``!‘‘).

We assume only a simple case of errors in transmission in which elements may be either truncated from the end of a morse word or added to the end of a morse word. When no perfect matches
for morse are found, display the word from context that matches the longest prefix ofmorse, or has the fewest extra elements beyond those in morse. If multiple
words in context match using these rules, any of these matches may be displayed. Words that do not match perfectly are displayed with a question mark (``?‘‘) suffixed.

The input data will only contain cases that fall within the preceding rules.

Input

The Morse code table will appear first and consists of lines each containing an uppercase letter or a digit C, zero or more blanks, and a sequence of no more than six periods and hyphens giving the Morse code for C. Blanks may precede or follow the items on
the line. A line containing a single asterisk (``*‘‘), possibly preceded or followed by blanks, terminates the Morse code table. You may assume that there will be Morse code given for every character that appears in the context section.

The context section appears next, with one word per line, possibly preceded and followed by blanks. Each word in context will contain no more than ten characters. No characters other than
upper case letters and digits will appear. Thered will be at most 100 context words. A line containing only a single asterisk (``*‘‘), possibly preceded or followed by blanks, terminates the context section.

The remainder of the input contains morse words separated by blanks or end-of-line characters. A line containing only a single asterisk (``*‘‘), possibly preceded or followed by blanks, terminates the input. No morse word
will have more than eighty (80) elements.

Output

For each input morse word, display the appropriate matching word from context followed by an exclamation mark (``!‘‘) or question mark (``?‘‘) if appropriate. Each word is to appear on a
separate line starting in column one.

Sample Input

A       .-
B       -...
C       -.-.
D       -..
E       .
F       ..-.
G       --.
H       ....
I       ..
J       .---
K       -.-
L       .-..
M       --
N       -.
O       ---
P       .--.
Q       --.-
R       .-.
S       ...
T       -
U       ..-
V       ...-
W       .--
X       -..-
Y       -.--
Z       --..
0       ------
1       .-----
2       ..---
3       ...--
4       ....-
5       .....
6       -....
7       --...
8       ---..
9       ----.
*
AN
EARTHQUAKE
EAT
GOD
HATH
IM
READY
TO
WHAT
WROTH
*
.--.....--   .....--....
--.----..   .--.-.----..
.--.....--   .--.
..-.-.-....--.-..-.--.-.
..--   .-...--..-.--
----        ..--
*

Sample Output

WHAT
HATH
GOD
WROTH?
WHAT
AN
EARTHQUAKE
EAT!
READY
TO
EAT!

对于多个精确匹配的, 输出字典序最小的和“!”。模糊匹配, 要输出匹配程度最高的(应该是吧……反正没什么害处)和“?”。用STL的话就很简单了,难一点的地方在模糊匹配的处理,其实也还好。有写注释,看代码吧。

#include<iostream>
#include<cstring>
#include<string>
#include<map>
#include<iterator>
using namespace std;

map<char, string>code;   //code数组存字母及其对应的莫尔斯电码
map<string, string>dict;     //dict数组存单词及其对应的电码序列

int main()
{
	char c;
	string cc;
	while (cin >> c&&c != '*')   //存字母的莫尔斯电码
	{
		cin >> cc;
		code[c] = cc;
	}

	/*
	map<char, string>::iterator it;
	for (it = code.begin(); it != code.end(); it++)
		cout << it->first << " " << it->second << endl;
    */

	string word;                  //存单词的电码序列
	while (cin >> word && word!="*")
	{
		string temp="";
		for (int i = 0; word[i]; i++)
			temp = temp + code[word[i]];
		dict[word] = temp;
	}

	/*
	map<string, string>::iterator it;
	for (it = dict.begin(); it != dict.end(); it++)
		cout << it->first << " " << it->second << endl;
	*/

	string s;
	while (cin >> s && s != "*")
	{
		int pipei = 0;
		map<string, string>::iterator it;//统计字典中有多少单词与这个电码序列匹配
		for (it = dict.begin(); it != dict.end(); it++)
		{
			if (it->second == s)
			{
				if (!pipei) cout << it->first;
				pipei++;
			}
		}
		if (pipei > 1) cout << '!';
		if (pipei == 0) //对不能精确匹配的序列特殊处理
		{
			string ans;
			string a;
			string b;
			int d;
			int dis=10e6;   //dis记录匹配程度(差几个字母)
			for (it = dict.begin(); it != dict.end(); it++)
			{
				a = it->second;
				b = s;
				if (b.size() < a.size()) swap(a, b); //substr函数返回0开始,长度为a串长度的副本
				if (a == b.substr(0, a.size())) //短序列是长序列的子串
				{
					d = b.size() - a.size();
					if (d < dis)     //遍历找打匹配程度最大的
					{
						dis = d;
						ans = it->first;
					}
				}
			}
			cout << ans << '?';
		}
		cout << endl;
	}

}

时间: 2024-10-12 19:38:07

UVA - 508 Morse Mismatches的相关文章

UVa 508 Morse Mismatches (模糊暴力)

题意:莫尔斯电码,输入若干个字母的Morse编号,一个字典和若干编码.对于每个编号,判断它可能的是哪个单词, 如果有多个单词精确匹配,输出第一个单词并加一个“!”:如果无法精确匹配,那么在编码尾部增加或删除尽量少的字符, 使其匹配某个单词并加上“?”. 析:第一次做的时候,一看啥呀,做不了,现在回来看看,发现可以做了,可以使用STL的map来做,首先先把每个字母做一个map, 然后把字典做一个map,最后输入时暴力一下,每个都找一下,这个增加字符可以这样想,就是在和字典比较时,短的在长的字符串中

【习题 4-6 UVA - 508】Morse Mismatches

[链接] 我是链接,点我呀:) [题意] 给你每个字母对应的摩斯密码. 然后每个单词的莫斯密码由其组成字母的莫斯密码连接而成. 现在给你若干个莫斯密码. 请问你每个莫斯密码对应哪个单词. 如果有多个单词和他对应.那么输出字典序最小的那个. 如果没有单词和他对应. 那么,你可以删除或者添加若干字母(只能一直删或一直增加) 问你在这种情况下能匹配到的单词(要求添加或者删的单词的数量最小) 如果有多种可能.输出字典序最小的. 如果一直删除.一直增加也找不到. 那么输出所有单词里面字典序最小的哪个. [

uva 508

模拟题,最大的坑就是正确理解题意,我英语太菜,读了两遍都没弄懂题意,于是边写边读题才弄明白,但最后还是没读出"无论是有多个相同还是模糊匹配都是按字典序输出第一个",以为是按输入顺序输出第一个,结果跪了,还有就是模糊匹配只有把那个不完整的 #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <map> #in

算法竞赛入门经典 第四章

[√ ] UVA1339 古老的密码 Ancient Cipher [√ ] UVA489 刽子手的游戏 Hangman Judge [√ ] UVA133 救济金发放 The Dole Queue [√ ] UVA213 信息解码 Message Decoding [√ ] UVA512 追踪电子表格中的单元格 Spreadsheet Tracking [√ ] UVA12412 师兄帮帮忙 A Typical Homework (a.k.a Shi Xiong Bang Bang Mang)

UVA 567 Risk【floyd】

题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=508 题意:20个点的任意最短路.floyd 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <string> #include <iter

UVa 568 Just the Facts

A过去后看了一下别人的解法,发现除了打表还有一种数论的方法. 分析一下阶乘后面的0是怎么出现的呢,当然是2乘5得到的. 我们将1~N先放在一个数组里面. 从数组第一个元素开始,先统计一下N!中因子为5的个数记为count,将其除去,然后再除去count个2.这样一来的话把所有元素乘起来后就不会出现10的倍数了. 当然并不是真正的乘起来,那样的话肯定是要溢出的,因为只关心最后一位数,所以每次乘完后求10的余数即可. 我的做法是打表,因为题目里给了N <= 10000的条件限制,所以可以把1~100

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f