Ananagrams STL练习C++题解

Ananagrams STL练习C++题解

Time limit1000 ms; Memory limit30000 kB

描述

Most crossword puzzle fans are used to anagrams — groups of words with the same letters in different orders — for example OPTS, SPOT, STOP, POTS and POST. Some words however do not have this attribute, no matter how you rearrange their letters, you cannot form another word. Such words are called ananagrams, an example is QUIZ. Obviously such definitions depend on the domain within which we are working; you might think that ATHENE is an ananagram, whereas any chemist would quickly produce ETHANE. One possible domain would be the entire English language, but this could lead to some problems. One could restrict the domain to, say, Music, in which case SCALE becomes a relative ananagram (LACES is not in the same domain) but NOTE is not since it can produce TONE. Write a program that will read in the dictionary of a restricted domain and determine the relative ananagrams. Note that single letter words are, ipso facto, relative ananagrams since they cannot be “rearranged” at all. The dictionary will contain no more than 1000 words.

输入

Input will consist of a series of lines. No line will be more than 80 characters long, but may contain any number of words. Words consist of up to 20 upper and/or lower case letters, and will not be broken across lines. Spaces may appear freely around words, and at least one space separates multiple words on the same line. Note that words that contain the same letters but of differing case are considered to be anagrams of each other, thus ‘tIeD’ and ‘EdiT’ are anagrams. The file will be terminated by a line consisting of a single ‘#’.

输出

Output will consist of a series of lines. Each line will consist of a single word that is a relative ananagram in the input dictionary. Words must be output in lexicographic (case-sensitive) order. There will always be at least one relative ananagram.

样例输入

ladder came tape soon leader acme RIDE lone Dreis peat ScAlE orb eye Rides dealer NotE derail LaCeS drIed noel dire Disk mace Rob dries
#

样例输出

Disk
NotE
derail
drIed
eye
ladder
soon

样例输入

Adventures in Disneyland Two blondes were going to Disneyland when they came to a fork in the road. The sign read: “Disneyland Left.” So they went home.

样例输出

a
adventures
blondes
came
disneyland
fork
going
home
in
left
read
road
sign
so
the
they
to
two
went
were
when

题目大意

大多数纵横字谜迷都习惯于用不同顺序的字母组合单词,例如opts、spot、stop、pots和post。但是,有些单词没有这个属性,无论如何重新排列字母,都不能形成另一个单词。这样的词叫做ananagrams,一个例子是quick。显然,这些定义取决于我们工作的领域;你可能认为雅典娜是一个阿纳格拉姆,而任何化学家都会很快产生乙烷。一个可能的领域是整个英语,但这可能导致一些问题。我们可以把音域限制为音乐,在这种情况下,音阶变成一个相对的符号(鞋带不在同一个域中),但音符不是,因为它能产生音调。编写一个程序,该程序将在受限域的字典中读取,并确定相关符号。请注意,单字母单词实际上是相对的符号,因为它们根本无法“重新排列”。字典将包含不超过1000个单词。

输入

输入将由一系列行组成。任何行的长度都不能超过80个字符,但可以包含任意数量的单词。单词最多由20个大写和/或小写字母组成,不会跨行中断。空格可以在单词周围自由出现,并且至少有一个空格在同一行上分隔多个单词。请注意,包含相同字母但大小写不同的单词被视为彼此的变位词,因此“绑定”和“编辑”是变位词。文件将以一行结束,该行由一个“”组成。

输出

输出将由一系列行组成。每一行将由输入字典中的一个相对符号组成。单词必须按词典(区分大小写)的顺序输出。总是会有至少一个相对的阿纳格拉姆。

代码

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <ctype.h>
#include <stdio.h>

#define PI 3.14159265358979383246
#define LL long long

#define _for(i, a) for(size_t i = 0; i < (a); ++i)
#define _rep(i, a, b) for(size_t i = (a); i < (b); ++i)

using namespace std;


struct cmpFunctor {
	inline bool operator()(const vector<char> &a, const vector<char> &b) {
		if (a[0] != b[0]) return a[0] < b[0];
		else if (a[1] != b[1]) return a[1] < b[1];
		else if (a[2] != b[2]) return a[2] < b[2];
		else if (a[3] != b[3]) return a[3] < b[3];
		else if (a[4] != b[4]) return a[4] < b[4];
		else if (a[5] != b[5]) return a[5] < b[5];
		else if (a[6] != b[6]) return a[6] < b[6];
		else if (a[7] != b[7]) return a[7] < b[7];
		else if (a[8] != b[8]) return a[8] < b[8];
		else if (a[9] != b[9]) return a[9] < b[9];
		else if (a[10] != b[10]) return a[10] < b[10];
		else return a[11] < b[11];
	}
};

int main() {
	vector<vector<char>> a;//用来存储小写字符串
	vector<vector<char>> b;//用来存储原来的字符串
	vector<char> xl, xu;//缓存要存进数组里的数据
	set<int> num;//存储将要删除的数的下标
	set<int>::iterator itnum;
	char c = 0;
	while ((c = getchar()) != '#') {
		if (c == ' ' || c == '\n') {
			b.push_back(xu);
			a.push_back(xl);
			xu.clear();
			xl.clear();
			while (((c = getchar()) != '#') && !isalpha(c));
			if (c == '#') {
				break;
			}
		}
		//printf("###%c%d\n", c, i);
		xu.push_back(c);
		c = tolower(c);
		xl.push_back(c);
	}
	//检验获取的数据
	//_for(i, a.size()) {
	//	cout << "###";
	//	_for(j, a[i].size()) {
	//		cout << a[i][j];
	//	}
	//	cout << endl;
	//}
	_for(i, a.size()) {
		sort(a[i].begin(), a[i].end());
	}
	//查找相同单词
	_for(i, a.size() - 1) {
		_rep(j, i + 1, a.size()) {
			if (a[i].size() == a[j].size()) {
				vector<char>::iterator iti = a[i].begin();
				vector<char>::iterator itj = a[j].begin();
				int f = 1;
				for (; itj != a[j].end(); itj++, iti++) {
					//iti = find(a[i].begin(), a[i].end(), *itj);
					if (*iti != *itj) {
						f = 0;
						break;
					}
				}
				//若找到相同的就删掉
				if (f) {
					num.insert(i);
					num.insert(j);
				}
			}
		}
	}
	itnum = num.end();
	itnum--;

	for (size_t i = 0; i < num.size();i++, itnum--) {
		//cout << *itnum << ' ';
		b.erase(*itnum + b.begin());
	}

	sort(b.begin(), b.end(), cmpFunctor());
	//while (b.size()) {
	//	int m = 0;
	//	_rep(i, 1, b.size()) {
	//		if (b[i][0] < b[m][0]) {
	//			m = i;
	//		}
	//	}
	//	_for(j, b[m].size()) {
	//		cout << b[m][j];
	//	}
	//	b.erase(b.begin() + m);
	//	cout << endl;
	//}

	_for(i, b.size()) {
		_for(j, b[i].size()) {
			cout << b[i][j];
		}
		cout << endl;
	}
	return 0;
}

本人也是新手,也是在学习中,勿喷

转载请注明出处

欢迎有问题的小伙伴一起交流哦~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值