整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

前端开发教程之CSS(五:显示属性、列表属性、定位属

前端开发教程之CSS(五:显示属性、列表属性、定位属性)

编今天的分享主题是显示属性、列表属性、定位属性;

首先,我们先来了解一下关于显示属性

显示属性,它表示了一个框或者盒的表现,具有2层含义,分别是显示方式显示效果

1.显示方式,即display属性,具体是指一个框的表示形式,它自己固定的取值候选:

a)none:表示让这个元素不显示,隐藏起来,同时这个元素是不占据这个文档的空间的。

b)block:表示让这个元素以块级元素的形式显示,在它后面的元素是会另外起一行,这个时候的元素是可以自己定义它的高度和宽度的。如果你想设置一个行内元素的高和宽,或者想让一个隐藏了的元素显示的话,这个方式就是非常好的。

c)inline:表示让这个元素以行内元素的形式显示,这个时候后面的元素会紧跟着前面的元素,并列显示,同事也不能设置高度和宽度。

d)inline-block:表示让这个元素以行内块的形式显示,其实就是一个行内元素,不过这个行内元素可以设置高度和宽度了。如果你不想让这个元素的后面元素另外起一行又想改变这个元素的高度和宽度,那这个方法是极好的。

以上4个候选取值,就是display的取值详解,语法规范就是display:none/block/inline/inline-block,具体的按照实实际开发需求。练习的时候,可以每个都试一试,看看它们分别是什么效果。

2.显示效果,就是元素显示了之后,再设置它的一些效果,先简单的介绍4个效果:

a)visibility属性,即表示这个元素的显示与否,取值有visible(显示的,也是默认值)、hidden(不显示),这个属性看似和上诉的显示方式挺像的,它们有一个非常明显的区别就是,display为none时,它是不占据空间的;而visibility为hidden时,它虽然是看不见的,但是它会占据页面空间,可能会影响文档的排版问题,这需要特别的注意。

b)opacity属性,即表示这个元素的透明度,取值范围就是0至1,其中0表示完全透明,1表示完全不透明,记住取值越大,越不透明。

c)vertical-align属性,即表示这个元素的垂直对齐,取值可以有:top/middle/bottom baseline;基线对齐

d)cursor属性即光标,表示当你的鼠标在经过这个元素时候,鼠标显示的样式;取值有:pointer(手的形状)、default(默认)、crosshair(显示为“+”)、text(显示为“I”)、wait(显示为 等待)、help(显示为“?”)

其次,我们了解一下列表属性

列表,就是讲这部分的内容按照一定的顺序排列,可以是横向的也可以是纵向的,她有列表样式属性、列表项图像属性、列表项位置、列表综合属性。

1.列表样式即list-style-type,分为有序列表、无序列表,有序的列表是按照数值排序、罗马数字排序,无序列表就是列表项为实心圆、空心圆、实心矩形。

无序列表的取值为:none(无标记)、disc(实心圆)、circle(空心圆)、square(实心矩形)

有序列表的取值为:none(无标记)、decimal(数字)、lower-roman(小写的罗马数字)、upper-roman(大写的罗马数字)

2.列表项图像即list-style-image,表示列表项图像不想取值为数字或者实心圆等时,可以自定义一个图像;语法规范:list-style-image:url(文件路径)

3.列表项位置即list-style-position,就是li前面标识的位置,取值有:outside(标识在li外)、inside(标识在li内)

4.列表的总和属性即list-style,语法规范:list-style:type url position 实例list-style:circle url(xxxx.jpg) inside

以上就是列表的一些样式了,可以自己打打代码,看看具体的效果

最后,我们了解一下定位属性

定位 position,就是元素在文档的位置,当需要对元素的位置进行修改时,就需要用到定位啦!

定位分为:普通流定位、浮动定位、相对定位、绝对定位、固定定位

定位的属性就是:position,取值有:static(静态定位即普通流定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)

display属性在使用的时候,需要配合top\bottom\left\right属性使用,表示偏移量。

z-index属性,表示当多个元素重叠的时候,谁在前面谁在后面,值越大越靠近用户

接下来详解各个定位:

1.相对定位:就是这个元素相对于自己本身的位置偏移指定的量数;具体的实现方式(二步曲)就是先定义定位方式,再定义指定偏移量:即display:relative;left\top\right:xxpx;常常用于弹出菜单的实现

2.绝对定位:就是这个元素相对了已经定义为相对定位的最近的父级;实现的方式同上,display为absolute,常用的场景非常多。

3.固定定位:就是将元素固定在网页的某个位置处,不跟随滚动条发生滚动;实现方式同上,display为fixed,常用于网页固定的小广告,多数情况下是相对与body实现固定定位的。

本篇文章开始成哥将带大家一起学习一下前端的基础知识,我们先讲解前端的基础HTML与CSS,这个讲完我们将讲解VUE前端框架,最后我们再讲讲Ant Design的VUE前端框架,从而形成前端一个系列的教程,下面就开始我们今天的内容吧!

01 HTML简介

HTML的英文全称是 Hyper Text Markup Language,即超文本标记语言。

HTML是由Web的发明者 Tim Berners-Lee和同事 Daniel W. Connolly于1990年创立的一种标记语言,它是标准通用化标记语言SGML的应用。用HTML编写的超文本文档称为HTML文档,它能独立于各种操作系统平台(如UNIX, Windows等)。

使用HTML语言,将所需要表达的信息按某种规则写成HTML文件,通过专用的浏览器来识别,并将这些HTML文件"翻译"成可以识别的信息,即现在所见到的网页。HTML 不需要编译,可以直接由浏览器执行,非常方便开发时调试。

02 HTML实例

我们现在创建一个典型的HTML结构具体如下:

1. <!DOCTYPE html>  
2. <html lang="ch">  
3. <head>  
4.     <meta charset="UTF-8">  
5.     <title>HTML实例</title>  
6. </head>  
7. <body>  
8.   <h1>我是标题</h1>  
9.   <p>我是段落。</p>  
10. </body>  
11. </html> 

如上页面中各个标签代表的意思如下:

1)<!DOCTYPE html>是文档声明头,它告诉游览器当前处理的内容是HTML页面

2)html是 HTML 页面的根元素,用于标识HTML内容的开始与结束

3) head是HTML页面的头,包含了文档的一些属性。其中meta是元数据这边charset="UTF-8"标识当前页面编码格式为UTF-8,title为文档的标题

4)body是HTML主体也是游览器在显示页面时的内容。h1是body内容中定义的标题,p是body内容中定义的段落

我们现在通过游览器打开编写的HTML内容,具体内容如下

在HTML中的内容可以通过以下格式进行内容注释具体如下:

03 HTML标签、元素、属性、实体编码与事件

(1)HTML标签

HTML 标签是 HTML 语言中最基本的单位,HTML 标签是 HTML(标准通用标记语言下的一个应用)最重要的组成部分。HTML标签具有如下特点:

1)标签一般是成对出现的 如:<div></div>;也有空标签 如:<br />

2)标签由<>包括,分为开始标签(开放标签)和结束标签(闭合标签)

3)标签不区分大小写,根据W3C(万维网联盟)推荐,统一使用小写字母

标签的示列如下:

标签按照<>的对数可以分为如下两类分别为双标签与单标签,下面我们具体来了解一下这两类标签。

1)双标签

双标签指由开始和结束两个标记符组成的标记。其基本语法格式如下:

1. <标记名></标记名>

常见的双标签有如下几种:

1. <html></html>  
2. <head></head>  
3. <title></title>  
4. <body></body>  
5. <h1></h1>  
6. <p></p>  
7.   
8. <!-- 块级元素 -->  
9. <div></div>  
10. <span></span>  
11.   
12. <!-- 超链接元素 -->  
13. <a></a>  
14.   
15. <!-- 列表元素 -->  
16. <ul></ul>  

2)单标签

单标签是指用一个标记符号即可完整地描述某个功能的标记。其基本语法格式如下:

1. <标记名/>

常见的单标签有如下几种:

1. <!-- 换行标签 -->  
2. <br />  
3.   
4. <!-- 分隔线标签 -->  
5. <hr />  
6.   
7. <!-- 图片标签 -->  
8. <img />  

(2)HTML元素

HTML 元素指的是从开始标签(start tag)到结束标签(end tag)的所有代码,如<p>段落</p>。元素可以进行嵌套具体如下:

1. <div>  
2.   <h1>我是标题</h1>  
3.     
4.   <div>  
5.     <p>元素嵌套示列</p>  
6.   </div>  
7.   
8. </div>  

(3)HTML属性

属性为 HTML 元素提供附加信息,可分为全局属性(即所有元素均可使用的属性,如id,class等)和元素属性(部分元素可使用的属性,例如<a href="http://www.baidu.com">搜索</a>),属性通常由属性名="属性值"构成,存在于开始标签中,示列如下:

(4)HTML实体编码

对于部分不易通过键盘输入的或和HTML冲突的部分符合,引入对应的"实体编码",如< <> >空格 。

(5)HTML事件

通过某个动作,执行某个操作/JS脚本的能力。如点击按钮,改变颜色,事件可以分为多类比多鼠标点击、鼠标聚焦等,下面我看看看一个事件编写示列:

04 HTML常用标签示列

(1)h标签

h 标签有六种分别为h1、h2、h3、h4、h5、h6,这六个分别对应六种样式的标题,我们现在来编写这六种h标签,演示代码如下:

1. <!DOCTYPE html>  
2. <html>  
3. <head>  
4.   <title>HTML基础教程</title>  
5.   <meta charset="utf-8" />  
6. </head>  
7. <body>  
8.   <h1>H1标题</h1>  
9.   <h2>H2标题</h2>  
10.   <h3>H3标题</h3>  
11.   <h4>H4标题</h4>  
12.   <h5>H5标题</h5>  
13.   <h6>H6标题</h6>  
14. </body>  
15. </html>  

我们来运行该HTML文件,来看看这六种h标签有什么样式差异,从示列中可以发现h1标签字体最大然后依次减小。

(2)p标签

p 标签是文本标签,现在我们来编写一段含有p标签的html文本,然后运行了看看p标签的样式具体操作如下:

1. <!DOCTYPE html>  
2. <html>  
3. <head>  
4.   <title>HTML基础教程</title>  
5.   <meta charset="utf-8" />  
6. </head>  
7. <body>  
8.   
9.   <h4>标题一</h4>  
10.   <p>我是段落1</p>  
11.   
12.   <h4>标题二</h4>  
13.   <p>我是段落2</p>  
14.   
15. </body>  
16. </html>  

(3)a标签

a标签是超链接标签,点击a标签可以跳转到其设置的网站,具体示列如下:

1. <!DOCTYPE html>  
2. <html>  
3. <head>  
4.   <title>HTML基础教程</title>  
5.   <meta charset="utf-8" />  
6. </head>  
7. <body>  
8.   <div>  
9.     <a href="http://www.baidu.com">点我跳转到百度页面</a>  
10.   </div>  
11.   
12.   <div>  
13.     <a href="http://www.qq.com">点我跳转到腾讯页面</a>  
14.   </div>  
15.   
16. </body>  
17. </html>  

(4)div标签

div标签是一个块级元素,它可用于组合其他 HTML 元素的容器。可以把div看成一个盒子,我们可以为这个盒子设置各种各样属性(如高度、宽度、颜色等),下面我们编写一个div标签并设置其长为300px,宽度为200px,同时给其一个背景颜色,具体如下:

1. <!DOCTYPE html>  
2. <html>  
3. <head>  
4.   <title>HTML基础教程</title>  
5.   <meta charset="utf-8" />  
6. </head>  
7. <body>  
8.   
9.   <div style="width: 200px;height: 300px;background: #2eabff">我是div元素</div>  
10.   
11. </body>  
12. </html>  

(5)列表标签

列表作为网页设计的重要内容之一,能够用来制作导航栏和新闻列表等。HTML 列表分为:有序列表(ol),无序列表(ul)以及自定义列表(dl)

1)有序列表ul

有序列表的顺序是有序的,默认情况下会以数字来排列,但也可以通过设置其type属性以大写字母、小写字母、大写罗马数字、小写罗马数字来排列,我们现在来写一个示列,具体如下:

1. <!DOCTYPE html>  
2. <html>  
3. <head>  
4.   <title>HTML基础教程</title>  
5.   <meta charset="utf-8" />  
6. </head>  
7. <body>  
8.   
9.   <!--  有序列表,以默认方式数字排列 -->  
10.   <p>有序列表默认方式数字排列</p>  
11.   <ol>  
12.     <li>列表1</li>  
13.     <li>列表2</li>  
14.     <li>列表3</li>  
15.   </ol>  
16.   
17.   <!--  有序列表,以大写字母排列 -->  
18.   <p>有序列表大写字母排列</p>  
19.   <ol type="A">  
20.     <li>列表1</li>  
21.     <li>列表2</li>  
22.     <li>列表3</li>  
23.   </ol>  
24.   
25. </body>  
26. </html>  

2)无序列表ol

无序列表的顺序是无序的,不会按照某个值来排序,无序列表中每个列表前默认都有一个实心圆,也可以通过type属性来设置成空心圆或者小方块,无序列表示列如下:

1. <!DOCTYPE html>  
2. <html>  
3. <head>  
4.   <title>HTML基础教程</title>  
5.   <meta charset="utf-8" />  
6. </head>  
7. <body>  
8.   
9.   <p>无序列表默认type样式</p>  
10.   <ul>  
11.     <li>列表1</li>  
12.     <li>列表2</li>  
13.     <li>列表3</li>  
14.   </ul>  
15.   
16.   <p>无序列表方块样式</p>  
17.   <ul type="square">  
18.     <li>列表1</li>  
19.     <li>列表2</li>  
20.     <li>列表3</li>  
21.   </ul>  
22.   
23. </body>  
24. </html>  

3)自定义列表dl

自定义列表以 <dl> 标签开始。每个自定义列表项以 <dt> 开始,其列表内容是以<dd> 开始,自定义列表前面没有任何标识,其具体示例如下:

1. <!DOCTYPE html>  
2. <html>  
3. <head>  
4.   <title>HTML基础教程</title>  
5.   <meta charset="utf-8" />  
6. </head>  
7. <body>  
8.   
9.   <p>自定义列表</p>  
10.   <dl>  
11.     <dt>东岳</dt>  
12.     <dd>泰山</dd>  
13.   
14.     <dt>南岳</dt>  
15.     <dd>衡山</dd>  
16.   
17.     <dt>西岳</dt>  
18.     <dd>华山</dd>  
19.   
20.     <dt>北岳</dt>  
21.     <dd>恒山</dd>  
22.   
23.     <dt>中岳</dt>  
24.     <dd>嵩山</dd>  
25.   </dl>  
26.   
27. </body>  
28. </html>  

(6)其它标签

1)换行标签<br/>

在HTML中如果想给内容进行换行可以使用换行标签,具体示列如下:

2)分割线标签<hr/>

<hr/> 标签用于在 HTML创建一条分割线,具体示列如下:

1. <!DOCTYPE html>  
2. <html>  
3. <head>  
4.   <title>HTML基础教程</title>  
5.   <meta charset="utf-8" />  
6. </head>  
7. <body>  
8.   
9.   <p>我是张三</p>  
10.   <!-- 分割线标签 -->  
11.   <hr/>  
12.   <p>我是李四</p>  
13. </body>  
14. </html>  

05 总结

至此我们《HTML基础教程上篇》就讲完了,下篇内容主要讲解HTML样式、HTML表单、Tabel等,敬请期待。最后如果喜欢本篇文章不要忘了点赞、关注与转发哦!

-END-

@IT管理局专注计算机领域技术、大学生活、学习方法、求职招聘、职业规划、职场感悟等类型的原创内容。期待与你相遇,和你一同成长。

文章推荐:

  • 一文秒懂Web框架基础之WSGI协议
  • IT工程师都需要掌握的容器技术之扫盲篇

、基础排序

排序是比较基础的算法,与很多语言一样,Python也提供了对列表的排序方法和内建排序函数。

1、两种排序方式

方式一:

li=[1, 3, 4, 9, 0]
li.sort()  # 提供方法

方式二:

li=[1, 3, 4, 9, 0]
li=sorted(li)  # 提供方法

两种方式都可以实现对列表元素的排序,从接受参数更能看出两者区别和相同点。

  • sort(key=None, reverse=False)
  • sorted(iterable, key, reverse)

2、不同点

(1):sort()属于列表对象特有的排序方法,因此调用方法直接在列表本身进行修改,返回值为None或者说无需返回值。
(2): sorted()属于python提供内建函数,无需导入可直接用,而从接受对象来看,sorted()方法可以直接接受iterable可迭代对象,因此作用对象更广泛,包括字符串,元组甚至字典都可以,返回一个列表,如下所示

test_string="dvsegh"
print(sorted(test_string)) # 输出['d', 'e', 'g', 'h', 's', 'v']
test_tuple=(5, 4, 3, 2, 1)
print(sorted(test_tuple)) # 输出[1, 2, 3, 4, 5]
test_list=[5, 4, 3, 2, 1]
print(sorted(test_list)) # 输出[1, 2, 3, 4, 5]
test_dic={1:"a", 2:"b", 0:"z"}
print(sorted(test_dic)) # 输出[0, 1, 2],字典的key作为排序结果返回

(3):对于Python3.x中的sort()无法函数自定义排序规则后面会说到。

3、相同点

(1):都支持reverse反转操作,参数reverse接收布尔类型,比如reverse=True,则表示排序结果逆序。

li=[1, 3, 4, 9, 0]
li.sort(reverse=True)
print(li)  # [9, 4, 3, 1, 0]

(2): 都支持关键函数排序,也就是key参数指定排序规则,参数的接收值为一个函数,该函数可以接收一个参数并返回一个值用来比较,如下,len接收字符串,返回长度作为比较值。

test_string="Hello World Welcome to My City"
print(sorted(test_string.split(" "), key=len))  # 根据字符串长度排序
# 输出:['to', 'My', 'City', 'Hello', 'World', 'Welcome']
print(sorted(test_string.split(" "), key=str.lower))  # 根据小写之后的字典序排序  
# 输出:['City', 'Hello', 'My', 'to', 'Welcome', 'World']

test_list=[-5, 4, 0, 2, 1]
print(sorted(test_list, key=abs))  # 根据绝对值排序 
# 输出:[0, 1, 2, 4, -5]

(3):更广泛的可以使用lambda表达式来完成更复杂排序。如下对二维列表多级排序

li=[
    [3 ,5],
    [5 ,0],
    [5 ,6],
    [3 ,-1],
    [2, 9]
]
# 多级排序
# 根据第一个元素从小打到排列,当第一个元素相等,按照第二个元素从大到小排列
li.sort(key=lambda x: (x[0], -x[1])) 
print(li)
#  输出 [[2, 9], [3, 5], [3, -1], [5, 6], [5, 0]]

也或者可以根据复杂对象的某些属性排序。对对象根据属性进行排序

# 学生对象,包括年龄,身高体重等
class Student:
    def __init__(self, age, height, weight):
        self.age=age
        self.height=height
        self.weight=weight

s1=Student(18, 180, 75)
s2=Student(19, 175, 80)
s3=Student(17, 176, 70)
s4=Student(18, 177, 65)
s5=Student(19, 180, 65)

# 班级里有很多学生
classes=[s1, s2, s3, s4, s5]
# 根据学生的年龄排序
classes.sort(key=lambda s: s.age)
for stu in classes:
    print("stu age: %d, height: %d, weight: %d" % (stu.age, stu.height, stu.weight))
    
输出:
stu age: 17, height: 176, weight: 70
stu age: 18, height: 180, weight: 75
stu age: 18, height: 177, weight: 65
stu age: 19, height: 175, weight: 80
stu age: 19, height: 180, weight: 65

从以上排序结果中相同年龄的学生还保持排序前的相对顺序,说明sort()排序也是稳定排序,sort()底层是基于合并排序和插入排序集合的一种更高效排序算法。以上是使用lambda表达式指定排序规则,也可以使用operator中提供的其他更加简洁的方式。

# 同样适用上述的Student例子
from operator import itemgetter, attrgetter

# 实现根据学生年龄排序
print(sorted(classes, key=attrgetter('age')))
print(sorted(classes, key=itemgetter(1)))
# 实现多级排序 新根据身高,再根据年龄排序
sorted(classes, key=attrgetter('height', 'age'))

二、排序进阶

其他语言中普遍提供的有cmp函数,也就是自定义更高级函数作为排序规则。而在python3.x中sort()不在支持cmp自定义函数比较,想要使用cmp,则需要是使用sorted(),并额外的做一些包装。

1、举例

比如,同样使用如上的Student例子,想要完成自定义排序规则,比如首先按照年龄大小排序,当年龄相同的时候按照体重逆序排序,如果体重也相同则按照身高逆序排序。

from functools import cmp_to_key

def func(stu1, stu2):
    # 年龄相同
    if stu1.age==stu2.age:
        # 体重相同 安装身高逆序
        if stu1.weight==stu2.weight:
            return stu2.height - stu1.height
        else: # 体重不同,逆序排序
            return stu2.weight - stu1.weight
    else: # 年龄不同,则按照年龄排序
        return stu1.age - stu2.age

class Student:
    def __init__(self, age, height, weight):
        self.age=age
        self.height=height
        self.weight=weight

s1=Student(18, 180, 55)
s2=Student(19, 175, 80)
s3=Student(17, 162, 70)
s4=Student(18, 177, 65)
s5=Student(19, 180, 65)
s6=Student(16, 160, 55)
s7=Student(17, 164, 70)

# 班级有7个学生
classes=[s1, s2, s3, s4, s5, s6, s7]
# 排序
classes=sorted(classes, key=cmp_to_key(func))
for stu in classes:
    print("stu age: %d, height: %d, weight: %d" % (stu.age, stu.height, stu.weight))
    
输出结果
stu age: 16, height: 160, weight: 55
stu age: 17, height: 164, weight: 70
stu age: 17, height: 162, weight: 70
stu age: 18, height: 177, weight: 65
stu age: 18, height: 180, weight: 55
stu age: 19, height: 175, weight: 80
stu age: 19, height: 180, weight: 65

对于sorted(iterable, key=lambda x:x),这种比较倾向于待排序的每个元素都有一个绝对的大小值作为排序标准,而有时候会绝对大小是根据两个元素才能得出的衡量,因此可以使用如上functools.cmp_to_key构建多个元素的比较函数。cmp_to_key包装后的自定义比较函数可以接受两个元素,将两个元素的对比结果作为返回值,另外注意,自定义的比较函数返回值需要是整型。

2、源码

cmp_to_key的源码如下

def cmp_to_key(mycmp):
    """Convert a cmp=function into a key=function"""
    class K(object):
        __slots__=['obj']
        def __init__(self, obj):
            self.obj=obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj)==0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <=0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >=0
        __hash__=None
    return K

cmp_to_key接收myfunc,并在内部定义一个K类并返回这个K类,这个类内部完成了各种比较运算符的重载(也就是mycmp的定义的排序规则),这个类是可调用的,在参与比较的时候其实是K的对象,而在使用lambda匿名表达式的时候使用是列表中的元素进行大小比较。如下:

li=[1, 0, 0, 8, 4]
sorted(li, key=lambda x: x)  # x代指li中的每个元素

三、真题

以下是笔试面试过程中遇到的关于一些自定义排序规则的题目。可以结合实际场景做下应用。
:以下只给出大概代码样例,水平有限,不保证完全正确。

1、题目一

(1):华为通用软件暑期实习笔试4.13场次算法题第一题
题干:硬件资源分配(不花点时间,题干都理不顺.....)
有M台服务器,每台服务器有以下属性:编号、CPU核数(1100)、内存、CPU架构(08)、是否支持NP加速的标识(0,1)。然后有一个资源分配要求,要求分配N台满足要求的服务器。具体如下:CPU核数>=cpuCount、内存>=memSize、CPU架构=cpuArch、是否支持NP加速=supportNP。其中,cpuCount、memSize、cpuArch、supportNP为这个要求输入的分配参数。
分配时会指定优先级策略,
策略如下
策略1:CPU优先,优先选择CPU核数满足分配要求并且最接近分配要求的cpuCount。如果CPU核数相同,在按内存满足要求并选择最接近memSize的服务器分配。
策略2:内存优先,优先选择内存满足分配要求并且最接近分配要求的memSize。如果内存相同,在按cpu核数满足要求并选择最接近cpuCount的服务器分配
如果两台服务器属性都相同,则按服务器编号从小到大选择(编号不会重复)
输入
第一行:服务器数量M
接下来M行为M台服务器属性的数组
下一行为分配要求:最大分配数量N,分配策略strategy,cupCount,memSize,cpuArch,supportNP
其中:
1<=M<=1000
1<=N<=1000
strategy:1表示策略1,2表示策略2
1<=cpuCount<=100
10<=memSize<=1000
0<=cpuArch<=8,另外,cpuArch使用9表示所有服务器架构都满足分配要求
0<=supportNP<=1,另外,为2时表示无论是否支持NP加速都满足分配要求
输出
先输出实际分配数量,后按照分配的服务器编号从小到大依次输出,以空格分开
样例1

输入
4
0,2,200,0,1
1,3,400,0,1
2,3,400,1,0
3,3,300,0,1
3 1 3 200 0 1
输出
2 1 3
解释:只有1和3满足要求,要求分配2台服务器,所以结果为2 1 3

样例2

输入
6
0,2,200,0,1
1,4,330,2,1
2,3,400,3,1
3,3,310,1,1
4,3,320,8,1
5,3,330,0,1
3 2 3 300 9 2
(这里注意一下输入的格式,最后一行是空格分开)
输出
3 3 4 5
解释:编号1~5都满足分配要求,按策略2分配即内存优先,内存>=300并且最接近300的服务器编号是3 4 1 5 2。
其中1和5内存相同,然后会比较CPU,即CPU>=3且最接近的,所以5优先于1.因此最后分配的三台服务器是3 4 5。
输出时先输出数量3,再按编号排序输出3 4 5

(2)思路自定义排序
主要先对一些特殊情况考虑,并且不同的策略不同的排序规则,但是都类似。

inp=list(map(int, input().strip().split(" ")))
N, strategy, cpuCount, memSize, cpuArch, SupportNP=inp
# N, strategy, cpuCount, memSize, cpuArch, SupportNP=2, 1, 3, 300, 9, 1

res=[]
for item in ans:
    if cpuArch !=9 and item[3] !=cpuArch:
        continue
    if SupportNP !=2 and item[4] !=SupportNP:
        continue
    res.append(item)

if strategy==1:
    res=list(filter(lambda item: item[1]>=cpuCount and item[2]>=memSize, res))
    # res=list(filter(lambda item: item[2]>=memSize, res))
    res.sort(key=lambda x: (x[1], x[2]))

    if len(res) <=N and len(res) > 0:
        tmp=[len(res)] + sorted([item[0] for item in res])
        print(" ".join([str(i) for i in tmp]))
    elif len(res) > N:
        tmp=[N] + sorted([res[i][0] for i in range(N)])
        print(" ".join([str(i) for i in tmp]))
    else:
        print(0)

elif strategy==2:
    res=list(filter(lambda item: item[2]>=memSize and item[1]>=cpuCount, res))
    # res=list(filter(lambda item: item[1]>=cpuCount, res))
    res.sort(key=lambda x: (x[2], x[1]))

    if len(res) <=N and len(res) > 0:
        tmp=[len(res)] + sorted([item[0] for item in res])
        print(" ".join([str(i) for i in tmp]))
    elif len(res) > N:
        tmp=[N] + sorted([res[i][0] for i in range(N)])
        print(" ".join([str(i) for i in tmp]))
    else:
        print(0)

2、题目二

(1)、华为通用软件暑期实习业务一面算法题
Leetcode最大数:链接https://leetcode-cn.com/problems/largest-number/
题干:
给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。
示例:
输入:nums=[3,30,34,5,9]
输出:"9534330"
(2)、三种思路
version1
由于没有看到nums数组的容量范围,第一反应直接全排列,然后对每一种结果作比较。

from itertools import permutations

nums=[3, 30, 34, 5, 9]

res=set(permutations(nums))  # 全排列结果去重
res=[int("".join(list(map(str, item)))) for item in res]  # 结果拼接再类型转换
print(max(res))  # 取最大值 输出 9534330

但是nums这么大范围,使用全排列做得无用功太多了,时间和空间复杂度都不满足。
version2
维持一个单调队列,队列中的元素拼接之后保证最大,逐个遍历当前元素,再往队列逐个位置尝试插入,并最终找到插入位置保持队列的规则。

class Solution:
    def largestNumber(self, nums: List[int]) -> str:
        queue=[]
        # 逐个遍历列表元素
        for i in range(len(nums)):
            # 队列为空,直接入队
            if len(queue)==0:
                queue.append(nums[i])
                continue
            # 假定当前nums[i]放在队尾,拼接后的值为mx
            mx_ind=-1
            mx=int("".join(list(map(str,  queue + [nums[i]]))))
            # 逐个插入队列中,作比较,谁大
            for j in range(len(queue)):
                tmp=int("".join(list(map(str,  queue[:j] + [nums[i]] + queue[j:]))))
                if tmp > mx:
                    mx=tmp
                    mx_ind=j
            # 找到插入位置
            if mx_ind !=-1:
                queue=queue[:mx_ind] + [nums[i]] + queue[mx_ind:]
            else:
                queue=queue[:] + [nums[i]]
        # 合并                
        st="".join(list(map(str, queue)))
        # 去除首部0
        st=st.lstrip("0")
        # 如果全为0,如nums=[0, 0],则输出0
        if len(st)==0:
            return "0"
        else:
            return st

执行结果:

version3
nums中的元素的位置不是由单一的元素决定,而是根据两个元素拼接之后的谁大决定的,如果"xy" > "yx",那就[x, y],否则[y, x]。因此可以使用自定义排序。

class Solution:
    def largestNumber(self, nums: List[int]) -> str:
        from functools import cmp_to_key
        def func(a, b):
            # 当前两元素长度相等,则按照大小排列
            if len(str(a))==len(str(b)):
                return b - a
            else:
            # 长度不同,则根据拼接后的大小排序
                return int(str(b)+str(a)) - int(str(a)+str(b)) 
        
        nums=sorted(nums, key=cmp_to_key(func))
        
        # 突然发现这样写更简洁 ,不用额外定义func   
        # nums=sorted(nums, key=cmp_to_key(lambda x, y: int(str(y)+str(x)) - int(str(x)+str(y))))

        s="".join(list(map(str, nums)))
        s=s.lstrip("0")
        if len(s) !=0:
            return s
        else:
            return "0"

执行结果:

3、题目三

(1)、荣耀通用软件暑期开发实习生笔试第二题
题目记不太清了,大概就是把日志文件中的一行一行记录根据时间戳排序,记录是字符串,不过整个记录中包含其他的一些无用字符串,因此要自己过滤出有用的时间戳。
实例输入:

5 
my/2019-01-01T09:00:01
my/2019-01-01T09:00:01
abc/2018-12-24T08:00:00/test/you
1/2018-12-24T08:00:00/test/Test1
123/2018-12-24T08:00:09/test/me

说明:5表示5行记录
输出:

1/2018-12-24T08:00:00/test/Test1
abc/2018-12-24T08:00:00/test/you
123/2018-12-24T08:00:09/test/me
my/2019-01-01T09:00:01

说明:优先根据时间戳信息排序,时间戳满足一定的格式XXXX-XX-XXTXX:XX:XX,T为分隔符,分割日期和时间,前半部分为日期,后半部分为时间,时间戳相同根据字符串长度排序,如果长度也相同,则按照首字母的ascii码表比较从小到大排序,如果两个记录字符串完全相同,则输出一条即可。
(2)、思路
主要还是自定义排序规则,不过对于所有记录都要做下处理判断是否满足时间戳规则,以及去重
代码如下

from functools import cmp_to_key

# 判断记录字符串是否符合时间戳格式
def is_time_format(s):
    if len(s) !=19:
        return False
    if s[4] !="-"  or s[7] !="-" or s[10] !="T" or s[13] !=":" or s[16] !=":":
        return False
    return True

# 自定义排序规则
def func(a, b):
    if a[0] !=b[0]:
        if a[0] > b[0]:
            return 1
        else:
            return -1
    else:
        if len(a[1]) !=len(b[1]):
            return len(a[1]) - len(b[1])
        else:
            return ord(a[1][0]) - ord(b[1][0])

# 处理输入
size=int(input().strip())
time_str=[]
for _ in range(size):
    # 并将记录分割成列表暂存起来
    tmp=input().strip().split("/")
    time_str.append(tmp)

# 保存满足时间戳的记录
res=[]
for i in range(len(time_str)):
    for j in range(len(time_str[i])):
        if is_time_format(time_str[i][j]):
            res.append([time_str[i][j],  "/".join(time_str[i])])
            break
res=sorted(res, key=cmp_to_key(func))  # 自定义排序

# 重塑结果
ans=[]
for i in range(len(res)):
    if res[i][1] not in ans:
        ans.append(res[i][1])

# 处理输出
print("\n".join(ans))

文章来自https://www.cnblogs.com/welan/p/16243852.html