Anagram acm入门题 day2---排列组合函数 比较函数的重写 第4题

You are to write a program that has to generate all possible words
from a given set of letters. Example: Given the word “abc”, your
program should - by exploring all different combination of the three
letters - output the words “abc”, “acb”, “bac”, “bca”, “cab” and
“cba”. In the word taken from the input file, some letters may appear
more than once. For a given word, your program should not produce the
same word more than once, and the words should be output in
alphabetically ascending order.

Input

The input consists of several words. The first line contains a number
giving the number of words to follow. Each following line contains one
word. A word consists of uppercase or lowercase letters from A to Z.
Uppercase and lowercase letters are to be considered different. The
length of each word is less than 13.

Output

For each word in the input, the output should contain all different
words that can be generated with the letters of the given word. The
words generated from the same input word should be output in
alphabetically ascending order. An upper case letter goes before the
corresponding lower case letter.

Sample Input

3
aAb
abc
acba

Sample Output

Aab
Aba
aAb
abA
bAa
baA
abc
acb
bac
bca
cab
cba
aabc
aacb
abac
abca
acab
acba
baac
baca
bcaa
caab
caba
cbaa

Hint

An upper case letter goes before the corresponding lower case letter.
So the right order of letters is ‘A’<‘a’<‘B’<‘b’<…<‘Z’<‘z’.

.
.
.
.
最后这里提出了排序的要求,因此需要重写比较函数
因为是要给出排列所有方案,这里直接用algorithm库的next_permutation()函数,这个函数会按照传入的比较函数格式给出下一组。
.
.

比较函数:返回值为bool类型,当返回true时不会进行互换,返回false才会进行互换,因此如果从小到大则直接return a<b(a<b的话返回true所以不用互换了),反之 return a>b。因为这里有比较要求,也就是同一个字母,大写字母比小写字母大也就是A>a >B>b…,详情请看cmp函数的注释

#include<algorithm> // next_permutation的头文件
#include <cstdio>
#include <cstring>
using namespace std;
static bool cmp(char& a, char& b)
{
	//1.如果同为大写或小写,直接按字母排序排序
    if ((a >= 'a' && a <= 'z' && b >= 'a' && b <= 'z')
     || (a >= 'A' && a <= 'Z' && b >= 'A' && b <= 'Z'))
        return a < b;
    else {
        if (a >= 'a' && a <= 'z')//2.小写字母在前的话
        {
        //2.1 将后面的大写字母转化为小写字母,方便比较
            char b1 = b + ('a' - 'A');
            if (b1 == a) {
                return false;//false则互换
                //2.2 由于两个字母是同个字母(如A,a),因此将大写字母换到前面
            }
            else  return a < b1;//2.3 否则就按顺序排序(小写的a还是比B大)
        }
        else {//3.大写字母在前的话
            char a1 = a + ('a' - 'A');//转化为小写
              //因为这次是大写字母在前,如果相等就不用换了,比如A a
            if (a1 == b) return true;//true则不互换
            else return a1 < b;
        }

    }

}
int main()
{
    char str[20];
    int n;
    scanf("%d", &n);
    while (n--)
    {
        scanf("%s", str);
        sort(str, str + strlen(str), cmp);
        //printf("%s", str);
        do
        {
            printf("%s\n", str);
        } while (next_permutation(str, str + strlen(str),cmp));
    }
    //str[13] = '\0';

}

当然,我重写的cmp函数很辣鸡,但是适合理解cmp函数是怎么运作的,下面是网上找的代码,看完觉得自己好像写了一堆屑

bool cmp(char a, char b)
{
	if (tolower(a) == tolower(b))//如果两个字母为同一个字母
		return a < b;//就按从小到大排序,也就是同种字母大写总是在小写前面
	else//如果不是同个字母,直接按字母升序排序
		return tolower(a) < tolower(b);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值