刚结束了离散数学的大作业,起初我是用Java去编写矩阵的幂运算的,但是老师说加前端页面会加分,后面我就用html+js简单完成了这个功能,并加入自反性、反自反性、对称性、反对称性及传递性等性质的判断。
下面是用Java对矩阵幂运算的编写:
import java.util.*;
public class Main {
public static void main(String[] args) {
//生成映射协助构造矩阵 最多支持10阶矩阵
Map map = new HashMap();
map.put("a",0);
map.put("b",1);
map.put("c",2);
map.put("d",3);
map.put("e",4);
map.put("f",5);
map.put("g",6);
map.put("h",7);
map.put("i",8);
map.put("j",9);
//System.out.println(map);
int a[][]=new int[10][10]; //R的关系矩阵
int b[][]=new int[10][10]; //幂运算后的结果矩阵
System.out.println("这里输入R的域,用逗号分隔");
Scanner scanner = new Scanner(System.in);
//去除逗号获取字符串长度判断为几阶矩阵
int order = scanner.next().replace(",","").length();
//判断 矩阵是不是在10阶或10阶以内
if(0<order && order<11){
System.out.println("这里输入R,即用<>包裹的数字对,例如<a,b><b,c>");
Scanner scanner1 =new Scanner(System.in);
String input = scanner1.nextLine().replace("<","").replace(">","").replace(",","");
String[] pairs = input.split("\\s+");
//根据R构造关系矩阵
for (String pair : pairs) {
for(int i=0; i<pair.length()-1; i+=2){
String row = pair.substring(i, i + 1);
String column = pair.substring(i + 1, i + 2);
int row1 = (int) map.get(row);
int column1 = (int) map.get(column);
a[row1][column1] = 1;
}
}
// 打印关系矩阵
System.out.println("R的关系矩阵为:");
for (int i = 0; i < order; i++) {
for (int j = 0; j < order; j++) {
System.out.print(a[i][j] + " ");
}
System.out.println();
}
while(true){
System.out.println("要计算的幂次数");
Scanner scanner2 = new Scanner(System.in);
int power = scanner2.nextInt();
//一次幂为本身
if(power == 1){
System.out.println("R的1次幂为:");
for (int i = 0; i < order; i++) {
for (int j = 0; j < order; j++) {
System.out.print(a[i][j] + " ");
}
System.out.println();
}
continue;
}
//计算次幂
else if (power > 1) {
int[][] c = new int[10][10];
//将矩阵c化为单位矩阵
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
if (i == j) {
c[i][j] = 1;
}
}
}
// 计算乘幂
for (int s = 0; s < power; s++) {
int[][] temp = new int[10][10];
// 矩阵a和矩阵c相乘
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
for (int k = 0; k < a.length; k++) {
temp[i][j] += a[i][k] * c[k][j];
}
}
}
// 矩阵c的值替换为临时矩阵的值
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
c[i][j] = temp[i][j];
}
}
}
// 矩阵b赋值
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
b[i][j] = c[i][j];
}
}
}
//0次幂
else if (power ==0) {
for(int i=0;i<a.length;i++)
for(int j=0;j<a.length;j++)
b[i][j]=0;
for(int i=0;i<a.length;i++)
b[i][i]=1;
}
else{
System.out.println("出错了");
}
//打印结果
System.out.println("计算后的矩阵为:");
for (int i = 0; i < order; i++) {
for (int j = 0; j < order; j++) {
System.out.print(b[i][j] + " ");
}
System.out.println();
}
clearArray(b);
System.out.println();
}
}else{
System.out.println("仅支持10阶及以下矩阵");
}
}
//清空数组
public static void clearArray(int[][] arr){
for(int i=0;i< arr.length;i++){
for (int j=0;j<arr.length;j++){
arr[i][j] =0;
}
}
}
}
运行结果如下图
这个只能在控制台上进行操作,加入了while循环方便多次操作
后来,为了加一点点分让绩点好看一点点,我就用html和js去重新写了这个功能
页面如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>矩阵幂运算</title>
<link href="./1.js" type="text/css">
<script type="text/javascript" src="./1.js"></script>
</head>
<body>
<div class="box"style="width:50%;float:left">
<div class="box1">
<p style="font-size: 20px">输入R的域,用逗号隔开:
<input id="ip1" style="height: 20px;margin-left: 206px" placeholder="a,b,c,d">
</p>
<p style="font-size: 20px">输入R,用<>包裹的数字对:
<input id="ip2" style="height: 20px;margin-left: 190px" placeholder="<a,c><bc><cd>">
</p>
<p style="font-size: 20px">输入要计算的幂次数:
<input id="ip3" style="height: 20px;margin-left: 240px">
</p>
</div>
<button style="width: 90px;height: 30px" onclick="miYunSuan()">生成矩阵</button>
<div class="box2">
<p id="xs1"></p>
<p id="xs2"></p>
<p id="xs3"></p>
</div>
</div>
</body>
</html>
放置了三个空的p,并分别给了id,用于后续关系矩阵、结果矩阵及性质的插入。
const a = []; //R的关系矩阵
const b = []; //幂运算后的结果矩阵
let map = new Map();
map.set("a",0);
map.set("b",1);
map.set("c",2);
map.set("d",3);
map.set("e",4);
map.set("f",5);
map.set("g",6);
map.set("h",7);
map.set("i",8);
map.set("j",9);
function miYunSuan(){
const order = document.getElementById("ip1").value.replace(/,/g, "").length; //去除逗号获取字符串长度判断为几阶矩阵
let power = parseInt(document.getElementById("ip3").value);
//判断矩阵是否10阶以内
if(0<order && order<=10 && power>=0){
for(var i=0;i<order;i++){ //定义二维数组
a[i] = [];
for(var j=0;j<order;j++){
a[i][j] = 0;
}
}
for(var i=0;i<order;i++){
b[i] = [];
for(var j=0;j<order;j++){
b[i][j] = 0;
}
}
const input = document.getElementById("ip2").value.replace(/</g, "").replace(/>/g, "").replace(/,/g, "");
// console.log(input)
const pairs = input.split(/\s+/); //将字符串分割成数组
//构造关系矩阵
for(let pair of pairs){
for(let i=0;i<pair.length-1;i+=2){
let row = pair.substring(i, i + 1);
let column = pair.substring(i + 1, i + 2);
let row1 = map.get(row);
let column1 = map.get(column);
a[row1][column1] = 1;
}
}
//console.log(a)
//将结果插入到xs1中
let output = "R的关系矩阵为:<br>";
for(let i=0; i<order;i++){
let rowHtml = '';
for (let j = 0; j < order; j++) {
rowHtml += a[i][j] + " ";
}
output += rowHtml + "<br>";
}
//关系矩阵插入
let xs1 = document.getElementById("xs1");
xs1.innerHTML = output;
//计算次幂
//一次幂为本身
if(power === 1){
let output = "R的一次幂为:<br>"
for(let i=0; i<order;i++){
let rowHtml = '';
for (let j = 0; j < order; j++) {
rowHtml += a[i][j] + " ";
}
output += rowHtml + "<br>";
}
//判断自反性、反自反性、对称性、反对称性、传递性。
let reflexive = true; //自反
let antiReflexive = true; //反自反
let symmetric = true; //对称
let antiSymmetric = true; //反对称
let transitivity = true; //传递性
//自反和反自反
for(var i=0;i<order;i++){
if(a[i][i]!==1){
reflexive = false;
}
if(a[i][i]!==0){
antiReflexive = false;
}
}
//对称和反对称
for(var i=0;i<order;i++){
for(var j=0;j<i;j++){
if(a[i][j] !== a[j][i]){
symmetric = false;
antiSymmetric = false;
}
else if(a[i][j] !== -a[j][i]){
antiSymmetric = false;
}
}
}
//传递性
for(var i=0;i<order;i++){
for(var j=0;j<order;j++){
if(a[i][j] !==0 ){
for(var k=0;k<order;k++){
if(a[j][k] !== 0 &&a[i][k] ===0){
transitivity = false;
}
}
}
}
}
//关系矩阵插入
let xs2 = document.getElementById("xs2");
let xs3 = document.getElementById("xs3");
xs2.innerHTML = output;
xs3.innerHTML = "自反性:" + reflexive +"<br>" + "反自反性:" + antiReflexive + "<br>" + "对称性:" + symmetric + "<br>" + "反对称性:" + antiSymmetric + "<br>" +"传递性:" + transitivity
}
//n次幂
else if(power>1){
const c = [];
for(var i=0;i<order;i++){ //定义二维数组
c[i] = [];
//将矩阵c化为单位矩阵
for(var j=0;j<order;j++){
if(i===j){
c[i][j] = 1;
}else{
c[i][j] = 0;
}
}
}
// console.log(c)
//计算乘幂
for(var s = 0;s<power;s++){
const temp = [];
for(var i=0;i<order;i++){ //定义二维数组
temp[i] = [];
for(var j=0;j<order;j++){
temp[i][j] = 0;
}
}
//矩阵a和c相乘
for(var i=0; i<order;i++){
for(var j=0; j<order;j++){
for(var k=0;k<order;k++){
temp[i][j] += a[i][k] * c[k][j];
}
}
}
//矩阵c的值替换为临时矩阵的值
for(var i=0;i<order;i++){
for(var j =0; j<order; j++){
c[i][j] = temp[i][j];
}
}
}
//矩阵b赋值
for(var i=0;i<order;i++){
for(var j=0;j<order;j++){
b[i][j] = c[i][j];
}
}
//判断自反性、反自反性、对称性、反对称性、传递性。
let reflexive = true; //自反
let antiReflexive = true; //反自反
let symmetric =true; //对称
let antiSymmetric =true; //反对称
let transitivity = true; //传递
//自反和反自反
for(var i=0;i<order;i++){
if(b[i][i]!==1){
reflexive = false;
}
if(b[i][i]!==0){
antiReflexive = false;
}
}
//对称和反对称
for(var i=0;i<order;i++){
for(var j=0;j<i;j++){
if(b[i][j] !== b[j][i]){
symmetric = false;
antiSymmetric = false;
}
else if(b[i][j] !== -b[j][i]){
antiSymmetric = false;
}
}
}
//传递性
for(var i=0;i<order;i++){
for(var j=0;j<order;j++){
if(b[i][j] !==0 ){
for(var k=0;k<order;k++){
if(b[j][k] !== 0 &&b[i][k] ===0){
transitivity = false;
}
}
}
}
}
let xs2 = document.getElementById("xs2");
let xs3 = document.getElementById("xs3");
let output = power+"次幂为:<br>";
for (let i = 0; i < order; i++) {
let rowHtml = '';
for (let j = 0; j < order; j++) {
rowHtml += b[i][j] + " ";
}
output += rowHtml + "<br>";
}
xs2.innerHTML = output;
xs3.innerHTML = "自反性:" + reflexive +"<br>" + "反自反性:" + antiReflexive + "<br>" + "对称性:" + symmetric + "<br>" + "反对称性:" + antiSymmetric +"<br>" + "传递性:" + transitivity
}
//0次幂
else if(power == 0){
for(var i=0;i<order;i++)
for(var j=0;j<order;j++)
b[i][j]=0;
for(var i=0;i<order;i++)
b[i][i]=1;
// 清空元素内容
let xs2 = document.getElementById("xs2");
let xs3 =document.getElementById("xs3");
xs2.innerHTML = "";
// 插入
let output = "0次幂为:<br>";
for (let i = 0; i < order; i++) {
let rowHtml = '';
for (let j = 0; j < order; j++) {
rowHtml += b[i][j] + " ";
}
output += rowHtml + "<br>";
}
xs2.innerHTML = output;
xs3.innerHTML = "自反性:" + "true" +"<br>" + "反自反性:" + "false" + "<br>" + "对称性:" + "true" + "<br>" + "反对称性:" + "false" +"<br>" + "传递性:" + "true"
}else{
let xs2 = document.getElementById("xs2");
xs2.innerHTML = "";
xs2.innerHTML = "出错了";
}
}else{
let xs2 = document.getElementById("xs2");
xs2.innerHTML = "";
xs2.innerHTML = "仅支持10阶及以下矩阵";
}
clearArray(b);
}
function clearArray(arr){
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; j++) {
arr[i][j] = 0;
}
}
}
运行结果如下图
仅支持10阶矩阵以内,可以通过增加映射的键值对去提高阶数