python写自动排课表软件

各位朋友们,小编在这里要揭秘,怎么用python写个自动排班表 基于python的排课表系统,一起揭开时间的面纱,探索过去的辉煌!

这篇文章主要介绍了python与java的区别与联系,具有一定借鉴价值,需要的朋友可以参考下python编程狮有没有库。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。

由于面试经常被cue使用Python和Java两种语言,到底有什么区别,从实际使用、基础数据类型、数据结构几方面整理下他们的区别。

总体区别:

1.Python比Java简单,学习成本低,开发效率高 2.Java运行效率高于Python,尤其是纯Python开发的程序,效率低 3.Java相关资料多,尤其是中文资料 6.Java偏向于商业开发,Python适合于数据分析 7.Java是一种静态类型语言,Python是一种动态类型语言 8.Java中的所有变量需要先声明(类型)才能使用,Python中的变量不需要声明类型 9.Java编译以后才能运行,Python直接就可以运行; 里的块用大括号对包括,Python 以冒号 + 四个空格缩进表示python自动化运维效果。 的类型要声明,Python 的类型不需要。 每行语句以分号结束,Python 可以不写分号。 13.实现同一功能时,JAVA 要敲的键盘次数一般要比 Python 多。

Python的基本数据类型与数据结构

一、基础数据类型

  标准数据类型:

    ·不可变数据类型(当值改变时,会产生新的id编号)

      Number(数字):int、float、bool、complex(复数)

      String(字符串)

      Tuple(元祖):不可变,无法通过下标来修改值

    ·可变数据类型(当值改变时,id编号不变化【可以使用id()函数来查看】)

      List(列表):[ ]

      Set(集合):{ }  

      Dictionary(字典):{ key:value}

二、基本数据结构(列表、集合、字典、元祖):

列表:list = [val1, val2, val3, val4],用中括号;元组:tuple = (val1, val2, val3, val4),用小括号;字典:dict = {key1: val1, key2: val2, key3: val3},用大括号;集合:set = {val1, val2, val3, val4},用大括号;

1.列表 list = [val1, val2, val3, val4],列表最显著的特征是:

列表中每个元素都是可变的;列表中元素是有序的,即每个元素都有一个位置;列表可以容纳Python的任何对象;

接下来看列表的增删改查: 增:

or_list = [1, "abc", 2.51]
or_list.append("JavaScript")    # append()方法在列表末尾追加元素(以整体形式追加)
or_list.insert(0, "Python")
print("or_list is: ", or_list)

用insert()方法可以实现在列表中增加元素。insert()方法需要写明增加在哪个位置和增加的内容,新元素的实际位置是在指定位置元素之前的位置;如果指定的位置不存在,默认会增加在列表末尾;

or_list = [1, "abc", 2.51]
or_list[0:0] = [9]      # [0:0]是指在列表中的第1个位置插入新元素
or_list[3:3] = "a"      # [3:3]是指在列表中的第4个位置插入新元素
print("or_list is: ", or_list)

上面的这两种方法都是天价单个元素,除了添加单个元素,还可以添加多个元素,用extend()方法来实现:

or_list = [1, "abc", 2.51]
ex_list = ["Python", 23, "game"]
or_list.extend(ex_list)         # extend()方法用于在列表末尾一次性追加另一个列表的多个值
print("or_list is: ", or_list)

删:

or_list = [1, "abc", 2.51]
or_list.remove(1)
print("or_list is: ", or_list)

删除列表元素除了remove()方法外,也可以用del关键字来声明:

del or_list[0:2]    # [0:2]删除第1个和第2个位置元素
print("or_list is: ", or_list)

改:

lst = [1, "abc", 2.51]
lst[0] = "start"
lst[2] = 777
print("lst is: ", lst)

如果想要替换掉列表中的某个元素,可以直接给列表某位置的元素重新赋值,lst[2]指lst列表中的第3个元素; 查: 列表的索引与字符串的索引类似,同样是分正反两种索引方式,可以从后往前,也可以从前往后所以,比如:

src_list = [1, "abc", 2.51]
# 输出第2个位置和倒数第1个位置的元素
print(src_list[1], src_list[-1])

# 输出第1、2个元素和第2到最后一个元素
print(src_list[:2], src_list[1:])

但是如果想查看某个元素的位置,就需要使用下面这种方式:

src_list = [1, "abc", 2.5, 360]
print(src_list.index(2.5))

这里需要注意的是,如果index()查找的元素不在列表里面,程序会产生ValueError:"xxx" is not in list

2.元组 tuple = (val1,val2,val3,val4),Python中的元组与列表类似,不同之处在于元组不可修改,类似于稳定版的列表,因此在列表中可以使用的增删改的方法在元组中是不可以使用的,但是可以对元组中的元素进行索引,和列表类似。

tup = (1, 2.5, "hello", 26, "abc")
print(tup[0])
print(tup[1])
print(tup[2])
print(tup.index(26))
print(tup.index("hello"))

同样的,index()方法查找的元素不在元组中时,会产生ValueError异常。

3.字典 dict = {key1:val1,key2:val2},编程世界中的很多概念都源自于生活,字典也是。这种数据结构如我们使用的字典一样,通过"名称->内容"来构建,在Python中每个元素都是带有冒号的kye与value的对应关系,习惯称之为键值对。字典的特征如下:

字典中的元素必须时键值对的形式;键(key)不可以重复,而值(value)可以重复;键不可变,无法修改;值可以修改,可以是任何对象;

即使字典中有重复的键,输出时也只会出现一次,比如:

d = {"A": "art", "B": "blog", "C": "ascii", "C": "cute", "C": "Java"}
print(d)        # {'A': 'art', 'C': 'Java', 'B': 'blog'}

接下来看字典的增删改查: 增: 字典中没有像列表那样的insert()方法,但是可以通过下面这种方式插入元素,元素默认插入在最后一个位置。

d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
d["D"] = "dictionary"
print(d)

再列表中可以通过extend()方法来为列表增加多个元素,在字典中可以使用update()方法来实现添加多个元素;

d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
d.update({"D": "dictionary", "E": "example"})
print(d)

删: 在字典中删除某个元素,也可以使用del关键字:

d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
del d["A"]
print(d)

需要注意的是,虽然字典是用大括号,但删除时依然使用中括号。

改: 如果要修改字典里的元素,直接重新给键赋值即可:

d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
d["B"] = "beyond"
print(d)

查: 在字典中进行查询时,跟删除一样需要通过字典的键来,也就是说对字典的查询和删除都是通过键来的:

d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
d["B"]
print(d["B"])

4.集合 set = {val1,val2,val3,val4},集合的概念有点接近数学上的集合。每个集合中的元素时无序的、不重复的任何Python对象,我们可以通过集合去判断数据的从属关系,有时还可以通过集合把数据结构中重复的元素过滤掉。集合不可以被切片也不能被索引,除了做集合运算外,集合元素可以被添加和删除。

s = {9, 3, 4, 6, 4, 2, 8}
s.add(5)        # 新增元素5
s.discard(4)    # 删除元素4
print(s)        # 输出的集合会从小到大排列,并取重:{2, 3, 5, 6, 8, 9}
Java的基本数据类型和数据结构 

一、基本数据类型

二、基本数据结构(数组、链表、栈、队列、二叉树、堆、散列表、图)

1.数组(一维数组、多维数组): 优点:内存空间连续,查询快,相对其他结构消耗内存空间小 缺点:初始化时就需要分配数组(内存)大小,不支持动态扩充,插入和删除慢

数组声明后会便会在连续内存空间中进行内存分配,并赋初始值

//此时,int[1] = 0
int[] array = new int[3];

2.链表:内存空间不连续,插入删除快,查询慢 单向链表,双向链表,循环单向链表,循环双向链表

//一种双向链表的实现
public class DoublePointLinkedList {
    private Node head;//头节点
    private Node tail;//尾节点
    private int size;//节点的个数
    
    private class Node{
        private Object data;
        private Node next;
        
        public Node(Object data){
             = data;
        }
    }
    
    public DoublePointLinkedList(){
        size = 0;
        head = null;
        tail = null;
    }
    
    //链表头新增节点
    public void addHead(Object data){
        Node node = new Node(data);
        if(size == 0){//如果链表为空,那么头节点和尾节点都是该新增节点
            head = node;
            tail = node;
            size++;
        }else{
             = head;
            head = node;
            size++;
        }
    }
    
    //链表尾新增节点
    public void addTail(Object data){
        Node node = new Node(data);
        if(size == 0){//如果链表为空,那么头节点和尾节点都是该新增节点
            head = node;
            tail = node;
            size++;
        }else{
             = node;
            tail = node;
            size++;
        }
    }
    
    //删除头部节点,成功返回true,失败返回false
    public boolean deleteHead(){
        if(size == 0){//当前链表节点数为0
            return false;
        }
        if( == null){//当前链表节点数为1
            head = null;
            tail = null;
        }else{
            head = ;
        }
        size--;
        return true;
    }
    //判断是否为空
    public boolean isEmpty(){
        return (size ==0);
    }
    //获得链表的节点个数
    public int getSize(){
        return size;
    }
   
}

3.栈:后进先出,栈顶可操作,栈底不可操作,不允许对栈中指定位置做增删操作。

public class SqStack<T> {
    private T data[];//用数组表示栈元素
    private int maxSize;//栈空间大小(常量)
    private int top;//栈顶指针(指向栈顶元素)
    
    @SuppressWarnings("unchecked")
    public SqStack(int maxSize){
        this.maxSize = maxSize;
         = (T[]) new Object[maxSize];//泛型数组不能直接new创建,需要使用Object来创建(其实一开始也可以直接使用Object来代替泛型)
         = -1;//有的书中使用0,但这样会占用一个内存
    }

    //判断栈是否为空
    public boolean isNull(){
        boolean flag = <=-1?true:false;
        return flag;
    }
    
    //判断是否栈满
    public boolean isFull(){
        boolean flag = ==this.maxSize-1?true:false;
        return flag;
    }
    
    //压栈
    public boolean push(T vaule){
        if(isFull()){
            //栈满
            return false;
        }else{
            data[++top] = vaule;//栈顶指针加1并赋值
            return true;
        }
    }

    //弹栈
    public T pop(){
        if(isNull()){
            //栈为空
            return null;
        }else{
            T value = data[top];//取出栈顶元素
            --top;//栈顶指针-1
            return value;
        }
    }
    
}

4.队列:先进先出。

public class SqQueue<T>{
    private T[] datas;//使用数组作为队列的容器
    private int maxSize;//队列的容量
    private int front;//头指针
    private int rear;//尾指针

    //初始化队列
    public SqQueue(int maxSize){
        if(maxSize<1){
            maxSize = 1;
        }
        this.maxSize = maxSize;
        this.front = 0;
         = 0;
        s = (T[])new Object[this.maxSize];
    }

    //两个状态:队空&队满
    public boolean isNull(){
        if(this.front == )
            return true;
        else
            return false;
    }

    public boolean isFull(){
        if((rear+1)%this.maxSize==front)
            return true;
        else
            return false;
    }

    //初始化队列
    public void initQueue(){
        this.front = 0;
        this.front = 0;
    }

    //两个操作:进队&出队
    public boolean push(T data){
        if(isFull())
            return false;//队满则无法进队
        else{
            datas[rear] = data;//进队
            rear = (rear+1) % maxSize;//队尾指针+1.
            return true;
        }
    }
    public T pop(){
        if(isNull())
            return null;//对空无法出队
        else{
            T popData = datas[front++];//出队
            front = (front+1) % maxSize;//队头指针+1
            return popData;
        }
    }

    //get()
    public T[] getDatas() {
        return datas;
    }

    public int getMaxSize() {
        return maxSize;
    }

    public int getFront() {
        return front;
    }

    public int getRear() {
        return rear;
    }
}

5.二叉树(ps:还有一个红黑树,2-3-4树)

class Node {
	int  value;
	Node leftChild;
	Node rightChild;
	
	Node(int value) {
		this.value = value;
	}
	
	public void display() {
		.print(this.value + "\t");
	}
 
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return String.valueOf(value);
	}
}
class BinaryTree {
	private Node root = null;
	
	BinaryTree(int value) {
		root = new Node(value);
		root.leftChild  = null;
		root.rightChild = null;
	}
	public Node findKey(int value) {}   //查找
        public String insert(int value) {}  //插入
        public void inOrderTraverse() {}    //中序遍历递归操作
        public void inOrderByStack() {}     //中序遍历非递归操作    
        public void preOrderTraverse() {}  //前序遍历
        public void preOrderByStack() {}   //前序遍历非递归操作
        public void postOrderTraverse() {} //后序遍历
        public void postOrderByStack() {}  //后序遍历非递归操作
        public int getMinValue() {} //得到最小(大)值
        public boolean delete(int value) {} //删除
}

6.堆(底层是完全二叉树,可以实现优先级队列。ps:此堆是一种特殊的二叉树与堆内存不是一个概念)

优先级队列(底层二叉树):最大优先队列(取出的是权值最大的元素)、最小优先队列(取出的是权值最小的元素) 7.Hash表:Hash值相同的对象不一定相同,但是相同的对象Hash值一定相同。线程不安全。

Hash地址的构建

直接取址法:取k 或k 的某个线性函数为Hash地址,这样取的值都不一样,但所需容量庞大 数字分析法:知晓k的数字规律,取产生冲突概率小的的值作为Hash地址 平方取中法:取k值平方数,取该平方数的中间几位,较常用 折叠法:分割k值,做叠加之类的处理 随机数法 PS:Hash函数的构造算法可能导致Hash地址的两个极限,Hash地址都一样则链表非常长,查询性能下降;Hash地址都不一样则HashMap(内部通过数组保存数据)可能会经过多次扩容,容量大增。

JDK Hash冲突的解决办法:JDK1.8之前采用链地址法(即用链表来保存下一个元素);JDK1.8增加了一个策略,使用常量TREEIFY_THRESHOLD(冲突的元素个数超过该常量)来控制是否切换到平衡树来存储

8.图(ps:还有带权图)三、常见集合

java集合框架大致可以分为以下几个部分:List列表、Set集合、Map映射、迭代器(Iterator、Enumeration)、工具类(Arrays、Collections;Arrays和Collections是用来操作数组、集合的两个工具类)。


原文地址1:https://blog.csdn.net/pingf123/article/details/135933652
python手册 http://www.78tp.com/python/

  • 28
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
遗传算法可以用来解决课问题。下面是一个基本的课程序实现。 首先,我们需要定义一个适应度函数,用来评估每个课方案的好坏。对于课问题,适应度函数可以考虑以下几个因素: 1. 每个班级上课时间不重叠。 2. 每个老师上课时间不重叠。 3. 每个教室不能同时被多个班级使用。 4. 每个班级的课程安不能超过限定的时间。 5. 班级之间的教学质量差异不大。 适应度函数的实现可以参考以下代码: ``` python def fitness_function(schedule): # 每个班级的上课时间不能重叠 for i in range(len(schedule)): for j in range(len(schedule)): if i != j and schedule[i]['time'] == schedule[j]['time']: return 0 # 每个老师的上课时间不能重叠 for teacher in teachers: time_list = [] for i in range(len(schedule)): if schedule[i]['teacher'] == teacher: time_list.append(schedule[i]['time']) if len(time_list) > len(set(time_list)): return 0 # 每个教室不能同时被多个班级使用 for classroom in classrooms: time_list = [] for i in range(len(schedule)): if schedule[i]['classroom'] == classroom: time_list.append(schedule[i]['time']) if len(time_list) > len(set(time_list)): return 0 # 每个班级的课程安不能超过限定的时间 for i in range(len(schedule)): if schedule[i]['time'] > max_time: return 0 # 班级之间的教学质量差异不大 diff = 0 for i in range(len(schedule)): for j in range(len(schedule)): if i != j and schedule[i]['class'] == schedule[j]['class']: if schedule[i]['time'] == schedule[j]['time']: diff += 1 elif abs(schedule[i]['time'] - schedule[j]['time']) == 1: diff += 0.5 return 1 / (1 + diff) ``` 接下来,我们可以使用遗传算法来搜索最优的课方案。基本的遗传算法框架如下: ``` python def genetic_algorithm(pop_size, num_generations, mutation_rate): # 初始化种群 population = initialize_population(pop_size) # 迭代 for i in range(num_generations): # 计算适应度 fitness_scores = [fitness_function(schedule) for schedule in population] # 选择 mating_pool = selection(population, fitness_scores) # 交叉 offspring = crossover(mating_pool) # 变异 for j in range(len(offspring)): if random.random() < mutation_rate: offspring[j] = mutation(offspring[j]) # 更新种群 population = offspring # 返回最优解 best_schedule = max(population, key=lambda x: fitness_function(x)) return best_schedule ``` 在实现遗传算法的过程中,我们需要设计以下几个函数: 1. initialize_population:初始化种群。 2. selection:选择操作。 3. crossover:交叉操作。 4. mutation:变异操作。 这些函数的具体实现可以根据具体问题进行设计。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值