问题来源:扑克牌排序(结构体部分的内容)*
题目描述
自定义结构体表示一张扑克牌,包含类型——黑桃、红桃、梅花、方块、王;大小——2,3,4,5,6,7,8,9,1
这里是引用
0,J,Q,K,A,小王(用0表示)、大王(用1表示)。输入n,输入n张扑克牌信息,从大到小输出它们的排序结果。
假设扑克牌的排序规则是大王、小王为第一大、第二大,剩余52张扑克牌按照先花色后大小排序。
花色:黑桃>红桃>梅花>方块。
大小: A>K>Q>J>>10>9>…>2。
输入
测试次数t
每组测试数据两行:
第一行:n,表示输入n张扑克牌
第二行:n张扑克牌信息,格式见样例
输出
对每组测试数据,输出从大到小的排序结果
样例输入
3
5
黑桃4 红桃10 梅花Q 方块K 黑桃A
10
大王 梅花10 红桃K 方块9 黑桃2 梅花A 方块Q 小王 黑桃8 黑桃J
5
红桃K 梅花K 黑桃K 方块K 小王
样例输出
黑桃A 黑桃4 红桃10 梅花Q 方块K
大王 小王 黑桃J 黑桃8 黑桃2 红桃K 梅花A 梅花10 方块Q 方块9
小王 黑桃K 红桃K 梅花K 方块K
博主在写此题时,一开始一直在想不清楚扑克牌结构体中应该放置什么样的内容。因为输入的数据是具有两个属性的:“花色”,“数值”。
后来经过老师的提醒,我上网查询到了一个函数,可以将输入的字符串切割开来,从而就可以获取两个属性值。
这个函数的名称是:strstr
**包含文件:string.h
函数名: strstr
函数原型:
extern char *strstr(char str1, const char str2);
(extern是计算机语言中的一个关键字,可置于变量或者函数前,以表示变量或者函数的定义在别的文件中。提示编译器遇到此变量或函数时,在其它模块中寻找其定义,另外,extern也可用来进行链接指定。)
语法:
* strstr(str1,str2)
str1: 被查找目标 string expression to search.
str2: 要查找对象 The string expression to find.
返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
通过此方法,可以找到查找字符串中目标字符串的首地址。(非0非NULL)
通过这个方法,就可以在遍历扑克牌结构体时确定扑克牌的花色和数值
如if(strstr(poke,“大王”))
if(strstr(poke,“K”))
而考虑到最后是要对扑克牌进行排序,对于输入的字符串,要判断大小比较困难,(因为要用两次Strstr获取花色首地址,数字首地址,而且还要考虑"大王”“小王”),因此可以用两个int型数据对字符串进行转义:int flag,int num
由此,可将扑克牌结构体定义为
struct poke{
char type[10];
int num;(转义数字)
int flag;(转义花色)
};
在主函数中就是将数据读入并完成转义的动作,较为简单,博主就不再赘述了。
在将数值读入每个结构体中的num和flag后,就需要进行排序动作了。
因为涉及到两个排序规则,所以sort函数的编写需要动些脑子。
下面转载了一些sort函数的用法:
https://www.cnblogs.com/czwangzheng/p/4593092.html
我的摘要:
sort函数使用模板:
sort包含在头文件algorithm中
sort(start,end,排序方法)
使用心得:
1.在Start应传入比较目标的首地址,而不是具体元素如 sort(arr,arr+10) sort(arr[0],arr[10])后一种写法是错误的
2.在没有传入排序方法是,其按升序排列。
3.若要让其按降序排列,可这样编写:
bool cmp(int a,int b){
return a>b;
}
将 cmp传入sort中
4.若根据结构体内的不同成员的成员值排序,如本题中的flag和num两个指标,则可以这样写
对于每个传入得p1和p2
若返回的是true,则按p1,p2排列
若返回的是false,则按p2,p1排列
bool cmp(poke p1,poke p2){//括号中得类型应该与sort()函数前两个元素的类型一致
if(p1.flag>p2.flag){
return true;
}
else if(p1.flag<p2.flag){
return false;
}
if(p1.num>p2.num)
return true;
else if(p1.num<p2.num)
return false;
return 1; //如果p1和p2得两个值都相同,则按true或false返回都行,此处用1
}