【扩展作业分享】JAVA, 数据结构与算法, *** 作系统, LUA

【扩展作业分享】JAVA, 数据结构与算法,  *** 作系统, LUA,第1张

类别目录
  • 一. 前言
  • 二. JAVA
    • (一). 作业
      • 1.
    • (二). 有趣代码
      • 1.
    • (三). 我的小黄鸭
      • 1. 抽象类实现接口
  • 三. 数据结构与算法
    • (一). 作业
      • 1.
    • (二). 有趣代码
      • 1.
    • (三). 我的小黄鸭
      • 1.Floyd算法
      • 2. LC --- 最长公共前缀
      • 3. LC --- 删除链表的倒数第N个节点
  • 四. *** 作系统
    • (一). 作业
      • 1. 第4章 进程调度与死锁在线作业
  • 五. LUA脚本语言(ReWord游戏开发)
    • (一).有趣小代码
      • 1.
    • (二). 面向对象
      • 1.
    • (三). 自定义开发框架
      • 1. 函数式框架
  • 六.其它

一. 前言

分享一些自己的作业内容,和自己的课外学习的一点有趣的东西, 欢迎参考借鉴批评.


二. JAVA (一). 作业 1.
(二). 有趣代码 1. (三). 我的小黄鸭 1. 抽象类实现接口

存在意义
当我们需要在一个接口里面定义多个方法但又不想全部实现这些方法时, 我们可以定义一个抽象类去实现这个接口, 再用一个普通的类(子类)去去继承这个抽象类(父类)即可.
解释
我们知道接口里面的抽象方法通过普通类实现时全部都需要重写, 而使用抽象类(父类)去实现接口时, 抽象类可以不重写接口里面的方法, 因为接口里面的方法和抽象类都由abstract关键字声明, 同属抽象概念, 因此在语法上并不会报错, 此时就需要普通类(子类)通过继承的抽象类(父类)去重写接口里面的方法了. 但显然这样做是没有意义的.

示例代码:

package com.mytest.www;

//测试抽象类(父类)
public abstract class AbstractTest implements ITest {
	// 抽象类只重写 碰火方法
	@Override
	public void fireAble() {} // 可以喷火
}
package com.mytest.www;

//测试接口
public interface ITest {
	void flyAble(); // 可以飞
	void fireAble(); // 可以喷火
}
package com.mytest.www;

public class Test extends AbstractTest {
	// 子类重写 飞方法
	@Override
	public void flyAble() {
		System.out.println("可以飞");
	} // 可以飞

	public static void main(String[] args) {
		Test test = new Test();
		test.flyAble();
		test.fireAble();
	}

}

结果

解释
从上面的代码中我们可以看到接口里面有两个方法, flyAble() 和 fireAble() , 但是我们在 Test 类里面只重写了 flyAble() , 并没有重写全部方法但是却没有报错, 这是为什么呢? 因为我们在 Test 类的父类 AbstractTest 类里面重写了 fireAble() 方法, 因此总的来说, 方法是全部覆写了的, 因此不会报错. 总之, 理解不了的时候,放大问题规模,包治百病.


三. 数据结构算法 (一). 作业 1. (二). 有趣代码 1. (三). 我的小黄鸭 1.Floyd算法
  • 应用方向:
    多源最短路径

  • 思路:
    转载自Ouyang_Lianjun的博客
    其实核心思路就是用每个节点充当桥梁连接两点, 进而来刷新任意两个点的最短距离, 当所有点都被充当过桥梁后自然所有点之间的距离最短了.

  • 代码示例:

    /**
     * 多源最短路径
     * 单向带权图
     * Floyd算法
     * input: 输入 n 表示 n * n 的矩阵, 接下来 n 行, 每行输入 n 个数据, 表示点 ni 和点 nj 的距离, -1 表示无穷
     * out: 任意两点间的最短距离
     */
     
    // 测试数据
    // 7
    // 0 12 -1 -1 -1 -1 14
    // 12 0 10 -1 -1 7 -1
    // -1 10 0 3 5 6 -1
    // -1 -1 3 0 4 -1 -1
    // -1 -1 5 4 0 2 8
    // 16 7 6 -1 2 0 9
    // 14 -1 -1 -1 -1 9 0
    
    #include
    using namespace std;
    typedef long long ll;
    #define N 450
    
    ll graph[N][N]; // 邻接矩阵
    
    // O(pow(n, 3)), 适用数据量在 1 <= n * n <= 2 * 1e5
    void floyd(int n) {
    	for (int k = 0; k < n; ++ k) // 中转点
    		for (int i = 0; i < n; ++ i) // 行
    			for (int j = 0; j < n; ++ j) // 列
    				graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]); // 刷新最短距离, 注意不要越界
    }
    
    int main() {
    	int n;
    	cin >> n;
    	// 建图
    	for (int i = 0; i < n; ++ i)
    		for (int j = 0; j < n; ++ j) {
    			cin >> graph[i][j];
    			graph[i][j] = (graph[i][j] == -1 ? INT_MAX: graph[i][j]);
    		}
    	// 计算
    	floyd(n);
    	// 输出
    	cout << "最短距离:" << endl;
    	for (int i = 0; i < n; ++ i)
    		for (int j = 0; j < n; ++ j)
    			cout << i + 1 << " -> " << j + 1 << " = " << graph[i][j] << endl;
    	return 0;
    }
    
  • 测试数据:

    7
    0 12 -1 -1 -1 -1 14
    12 0 10 -1 -1 7 -1
    -1 10 0 3 5 6 -1
    -1 -1 3 0 4 -1 -1
    -1 -1 5 4 0 2 8
    16 7 6 -1 2 0 9
    14 -1 -1 -1 -1 9 0

  • 运行结果:
    在g++(std = c++11)编译通过

  • 解析:

    测试数据图:


    使用邻接矩阵存储
    A => A 的距离为0, A => B 的距离为12, A => C 的距离为-1(表示无穷, 因目前还不知道具体距离), A => D 的距离-1, A=> E 的距离-1, A => F 的距离16, A => G 的距离14;
    B => A 的距离12, B => B 的距离0, B => C 的距离10, B => D 的距离-1, B => E 的距离-1, B => F 的距离7, B => G 的距离-1,;
    其余依次推即可得到测试数据
    时间复杂度
    O(n^3), n为节点数, 例如上图的点 A~G

2. LC — 最长公共前缀

题目

知识点
在做这道题之前, 我们需要先知道以下概念:

  1. 字符串的前缀:
    转载自moodfriend的博客
  2. substr()
    转载自哦啦哦啦!的博客
  3. strstr()
    转载自the_tops的博客
  4. c_str()
    转载自Lemonbr的博客

思路
由于我们需要返回的是最大的公共前缀, 因此我们不妨设第一个字符串为我们的最大公共前缀, 那么接下来我们只需要判定其可不可以在后续的字符串中找到即可, 若找不到我们就对其从首地址开始切片, 直到通过strstr() 函数返回的地址不等于NULL(主串找到了最大公共前缀子串)且该地址等于主串第一个元素的首地址(保证是前缀串), 值得注意的是, 当我们的子串为空串时, 我们通过strstr() 函数返回的也是主串的第一个元素的地址, 因此我们并不需要额外判定子串长度.

示例代码

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        int len = strs.size();
        string str = strs[0];
        for (int i = 1; i < len; ++ i) {
            while (strstr(strs[i].c_str(), str.c_str()) != &strs[i][0])
                str = str.substr(0, str.length() - 1);
        }
        return str;
    }
};

结果

3. LC — 删除链表的倒数第N个节点

题目

思路
因为题目给我们的列表的头节点是一个假的头节点(有数据), 因此我们需要自己定义一个头节点. 对于题目要求的一次扫描, 我们如果可以知道我们需要移动的位置, 那么我们便可以达到一次扫描,所以我们可以这么 *** 作: 我们知道, 我们需要的是删除倒数位置的节点, 那么如果我们正数呢? 显然会有一个相同的结果 – 余下的移动位数相同, 例如长度为5的链表([1, 2, 3, 4, 5]), 我们要删除倒数第3个节点, 那么倒数3位后位于2位置, 我们在移动一位就遍历结束, 那么如果我们正向移动3位后呢? 显然位于4位置, 同样的我们在移动一位就遍历结束. 因此我们只要从头节点开始移动一位即可.

示例代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
          ListNode* Realhead = new ListNode;
          Realhead -> next = head;
          ListNode *R = Realhead, *L = Realhead;
          // 确定L指针需要移动的位置
          for (int i = 0; i < n; i ++) {
              R = R -> next;
          } 
          while (R -> next != NULL) { // 用R限制L的移动距离
              R = R -> next;
              L = L -> next;
          }
          ListNode* Next = L -> next;
          L -> next = Next -> next;
          Next -> next = NULL;
          return Realhead -> next;
    }
};

运行结果

解释
建立一个真正的头节点 Realhead 指向 head , 定义两个指向头节点的指针 L 和 R , R 用来确定 L 要移动到的位置, L 用来指向要删除的节点, 最后返回 Realhead 的下一节点即可.

时间复杂度
O(n)


四. *** 作系统 (一). 作业 1. 第4章 进程调度与死锁在线作业
总得分: 80.0
一.单选题(共10题,50.0分)
1.在为多道程序所提供的可共享的系统资源不足时,可能出现死锁,但是,不适当的(     )也可能产生死锁。
A、进程优先权
B、资源的线性分配
C、进程推进顺序
D、分配队列优先权
正确答案: C 我的答案:C得分: 5.0分

2.进程调度是从(     )选择一个进程投入运行。
A、就绪队列
B、等待队列
C、作业后备队列
D、提交队列
正确答案: A 我的答案:A得分: 5.0分

3.银行家算法是一种(     )算法。
A、死锁解除

B、
死锁避免
C、死锁预防
D、死锁检测
正确答案: B 我的答案:B得分: 5.0分

4.(   )优先权是在创建进程时确定的,确定之后在整个进程运行期间不再改变。
A、先来先服务
B、静态
C、动态
D、短作业
正确答案: B 我的答案:B得分: 5.0分

5. *** 作系统的作业管理是一种(    )。
A、宏观的高级管理
B、宏观的低级管理
C、系统刚开始加电
D、初始化引导完毕
正确答案: A 我的答案:A得分: 5.0分

6.作业调度的关键在于(   )。
A、选择恰当的进程管理程序
B、选择恰当的作业调度算法
C、用户作业准备充分
D、用一个较好的 *** 作环境
正确答案: B 我的答案:A得分: 0.0分

7.为了对紧急进程或者重要进程进行调度,调度算法应采用(    )。
A、先来先服务法
B、短作业优先法
C、时间片轮转法
D、优先级法
正确答案: D 我的答案:D得分: 5.0分

8.在 *** 作系统中,(    )负责对进程进行调度。
A、处理机管理
B、作业管理
C、高级调度管理
D、存储和设备管理
正确答案: A 我的答案:A得分: 5.0分

9.两个进程争夺同一个资源(    )。
A、一定死锁
B、不一定死锁
C、不死锁
D、以上说法都不对
正确答案: B 我的答案:B得分: 5.0分

10.在非剥夺调度方式下,运行进程执行V原语后,其状态(    )。
A、不变
B、要变
C、可能要变
D、可能不变
正确答案: A 我的答案:C得分: 0.0分

二.判断题(共10题,50.0分)
1.对信号量S的P-V *** 作的含义是:P(S)是释放资源,V(S)是申请资源。
我的答案:× 得分: 5.0分正确答案:×

2.一般而言,由于 *** 作系统的并行与共享以及随机性等特点,通过预防与避免的手段达到排除死锁的目的是一件非常困难的事情。
我的答案:√ 得分: 5.0分正确答案:√

3.对于并发进程,同步与互斥是一个必要条件。
我的答案:× 得分: 0.0分正确答案:√

4.进程调度属于高级调度。
我的答案:× 得分: 5.0分正确答案:×

5.吞吐量是指系统在单位时间内所完成的作业或者进程的数量。
我的答案:√ 得分: 5.0分正确答案:√

6.CPU利用率是指CPU空闲时间与总的运行时间的比值。
我的答案:× 得分: 5.0分正确答案:×

7.每个作业的加权周转时间定义该作业的周转时间与该作业的提交时间的比值。
我的答案:× 得分: 5.0分正确答案:×

8.打印机是可剥夺的一种资源。
我的答案:√ 得分: 0.0分正确答案:×

9.若某一时刻系统中不存在一个安全序列,则称此时的系统状态为不安全状态。
我的答案:√ 得分: 5.0分正确答案:√

10.系统的每个进程对各种资源的仍然需求数量等于每个进程对各种资源最大需求量与已经给该进程分配的资源数量的差值。
我的答案:√ 得分: 5.0分正确答案:√

错误分析:
原语一旦开始执行,就要连续执行完,不允许中断
并发一定需要同步和互斥相互配合
打印机不是可剥夺的一种资源


五. LUA脚本语言(ReWord游戏开发) (一).有趣小代码 1. (二). 面向对象 1. (三). 自定义开发框架 1. 函数式框架
  • 请访问我的网站
    https://myrainbowcolor.github.io/Rworlder/#/

六.其它

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/734719.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存