安卓课设版算法计算器(HNUST)
前言:
如果只想看函数使用说明请跳转到“四、使用函数介绍”
该版本为课设版,富含多个界面,是前版的plus版本,进行了更多的复杂化操作,故因此会觉得对于计算器有点“大可不必”,但为了完善这个版本,小作者还是把其当作一个项目去做,也因此收获了些许。
课设要求
1、目的与要求
1、掌握布局及常用控件Button、TextView、ListView等
2、掌握SQLite数据库及其使用
3、实现基础计算器及算法计算器
2、功能需求
算法计算器主要分为5个主要模块,包括:登录模块、使用记录模块、普通计算器模块、算法计算器模块、使用说明模块。争对C语言基础入门,以及日常快速进行特殊计算,下载到手机端以方便快速使用。
界面:
- 验证登录界面
- 选择计算器界面
- 常规计算器界面
- 算法计算其界面
- 使用说明模块界面(使用说明文档链接、使用记录)
1、验证登录:通过验证身份进行跳转
2、选择界面:两个点击按钮,可跳转常规以及算法计算器
3、常规计算器界面:用堆栈复刻基础计算器,但可以实现多项式计算
4、算法计算器界面:集成数学算法,可用于快速求解,由大量算法板子组成,覆写为Java版本以使用在安卓应用开发中
5、使用说明模块界面:内置说明文档跳至链接,以及数据库记录各大算法的使用次数
一、实现做法
1、创建一个新文件——Empty Views Activity
2、下面的感叹号是因为我已经创建过一个了(可以忽略)
3、等待Building
4、实现过程
1、按照步骤1~3分别创建Login
,MainActivity
,MainActivity1
,MainActivity2
,MainActivity3
,MainActivity4
(界面是什么,以及其他信息在第二部分)
2、创建一个类,名称为DatabaseHelper
,用来使用SQLite(内置数据库)
3、创建类MathUtils(数学函数库)
4、把对应代码写入对应的文件中
5、此时需要有一个可视化数据库的工具——(这里用的Navicat Premium16)
在下面文件找到对应的数据库表格位置,然后复制到Navicat中
我的是:C:.\AppData\Local\Google\AndroidStudio2024.1\device-explorer\Pixel 8a API 26_\data\data\com.example.algoritmcalculator\databases\itcast.db(一定要精确到itcast.db)
二、页面介绍
- 验证登录界面
- 选择计算器界面
- 常规计算器界面
- 算法计算其界面
- 使用说明模块界面(使用说明文档链接、使用记录)
下面依次介绍这些界面的实现和作用
验证登录界面
展示:
实现逻辑: 通过取出组件中的字符串,对目标字符串进行匹配,正确则进入,错误则提示密码错误。
选择计算器界面
展示:
实现逻辑: 通过三个按钮,通过隐式intent进入不同板块
常规计算器界面
展示:
实现逻辑: 通过栈计算式子,可实现复合运算
算法计算器界面
展示:
实现逻辑: 较为复杂,每个函数都有其对应逻辑,具体使用见下文的使用说明,大体的逻辑是通过取出数据,然后更具不同的操作进行函数运算,然后获取返回值后传回界面中。同时要记录每个函数的使用次数,更新数据库。
说明:
除了GAUSS函数需要换行,其他的每个数中间一定要有空格,否则的话会导致出现不可预测的问题,GAUSS函数的输入方式后文也有写,这里提一句,由于不可抗因素导致加一个换行键会很丑,采用粉色按钮如果此次点击与上次点击同时为GAUSS按钮时,会换行
使用说明模块界面
展示:
实现逻辑: 一个超链接按钮,来到此处,以及通过数组获取到数据库中的使用次数,并刷新界面。
三、详细代码
Java代码
DatabaseHelper
package com.example.algoritmcalculator;import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;public class DatabaseHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME = "AlgoCalculator.db";private static final int DATABASE_VERSION = 2;public static final String TABLE_NAME = "algorithm_usage";public static final String COLUMN_ID = "id";public static final String COLUMN_ALGORITHM = "algorithm";public static final String COLUMN_COUNT = "count";public DatabaseHelper(Context context){super(context,"itcast.db",null,1);}@Overridepublic void onCreate(SQLiteDatabase db) {
// db.execSQL(TABLE_CREATE);// 创建名为 algorithm_usage 的表db.execSQL("CREATE TABLE algorithm_usage (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT, " + "count INTEGER" + ")");}// count+1 操作public void incrementAlgorithmCount(int id) {SQLiteDatabase db = this.getWritableDatabase(); // 获取可写数据库实例Cursor cursor = db.rawQuery("select * from algorithm_usage where id = ?",new String[]{String.valueOf(id)});if(cursor.getCount() != 0){while(cursor.moveToNext()){int count = cursor.getInt(cursor.getColumnIndex("count")); // 此处报错不必理会,不会出现-1db.execSQL("update algorithm_usage set count=? where id=?", new Object[]{count + 1, id});}}}// 获取countpublic List<Integer> getAlgorithmCounts() {SQLiteDatabase db = this.getReadableDatabase();List<Integer> counts = new ArrayList<>();Cursor cursor = db.rawQuery("SELECT count FROM algorithm_usage", null);if (cursor.moveToFirst()) {do {int count = cursor.getInt(0); // 获取当前行的count值 列counts.add(count); // 将count值添加到列表中} while (cursor.moveToNext());}cursor.close();db.close();return counts; // 返回包含所有算法count值的列表}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}
Login
package com.example.algoritmcalculator;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;public class Login extends AppCompatActivity {private EditText passwordEditText;private Button loginButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);passwordEditText = findViewById(R.id.passwordEditText);loginButton = findViewById(R.id.loginButton);loginButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String password = passwordEditText.getText().toString();// 这里只是一个示例,实际应用中应该检查密码是否正确if ("lixuyun666".equals(password)) {Toast.makeText(Login.this, "Login Successful", Toast.LENGTH_SHORT).show();// 跳转到应用的主界面或其他界面redirectToMainActivity();} else {Toast.makeText(Login.this, "Login Failed", Toast.LENGTH_SHORT).show();}}});}private void redirectToMainActivity() {Intent intent = new Intent(Login.this, MainActivity.class);startActivity(intent);// 如果您不希望用户返回到登录界面,可以添加以下代码finish();}
}
MainActivity
package com.example.algoritmcalculator;import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});Button button = findViewById(R.id.button);button.setOnClickListener(view -> {Intent intent = new Intent(this, MainActivity2.class);startActivity(intent);});Button button2 = findViewById(R.id.button2);button2.setOnClickListener(view -> {Intent intent = new Intent(this, MainActivity3.class);startActivity(intent);});Button button3 = findViewById(R.id.button3);button3.setOnClickListener(view -> {Intent intent = new Intent(this, MainActivity4.class);startActivity(intent);});}
}
MainActivity2
package com.example.algoritmcalculator;import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import java.util.Stack;public class MainActivity2 extends AppCompatActivity implements View.OnClickListener {private final static String TAG = "CalculatorActivity";private TextView tv_result; // 声明一个文本视图对象private String operator = ""; // 运算符private String firstNum = ""; // 第一个操作数private String secondNum = ""; // 第二个操作数private String result = ""; // 当前的计算结果private String showText = ""; // 显示的文本内容private Stack<Double> num = new Stack<>();private Stack<Character> op = new Stack<>();private int[] priority = new int[256];{priority['+'] = priority['-'] = 1;priority['*'] = priority['/'] = 2;}@SuppressLint("MissingInflatedId")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main2);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main2), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});// 从布局文件中获取名叫tv_result的文本视图tv_result = findViewById(R.id.tv_result);// 下面给每个按钮控件都注册了点击监听器findViewById(R.id.btn_cancel).setOnClickListener(this); // “取消”findViewById(R.id.btn_divide).setOnClickListener(this); // “除法”findViewById(R.id.btn_multiply).setOnClickListener(this); // “乘法”findViewById(R.id.btn_clear).setOnClickListener(this); // “清除”findViewById(R.id.btn_seven).setOnClickListener(this); // 7findViewById(R.id.btn_eight).setOnClickListener(this); // 8findViewById(R.id.btn_nine).setOnClickListener(this); // 9findViewById(R.id.btn_plus).setOnClickListener(this); // “加法”findViewById(R.id.btn_four).setOnClickListener(this); // 数字4findViewById(R.id.btn_five).setOnClickListener(this); // 数字5findViewById(R.id.btn_six).setOnClickListener(this); // 数字6findViewById(R.id.btn_minus).setOnClickListener(this); // “减法”findViewById(R.id.btn_one).setOnClickListener(this); // 数字1findViewById(R.id.btn_two).setOnClickListener(this); // 数字2findViewById(R.id.btn_three).setOnClickListener(this); // 数字3findViewById(R.id.ib_left).setOnClickListener(this); // (findViewById(R.id.btn_zero).setOnClickListener(this); // 数字0findViewById(R.id.btn_dot).setOnClickListener(this); // “小数点”findViewById(R.id.btn_equal).setOnClickListener(this); // “等号”findViewById(R.id.ib_right).setOnClickListener(this); // )}@Overridepublic void onClick(View v) {String inputText;inputText = ((TextView) v).getText().toString();Log.d(TAG, "inputText=" + inputText);if (v.getId() == R.id.btn_clear) { // 点击了清除按钮clear();}else if (v.getId() == R.id.btn_cancel) { // 点击了取消按钮refreshText(showText.substring(0, showText.length() - 1));}else if (v.getId() == R.id.btn_plus || v.getId() == R.id.btn_minus || v.getId() == R.id.btn_multiply || v.getId() == R.id.btn_divide) { // +-*/operator = inputText;refreshText(showText + operator);}else if (v.getId() == R.id.btn_equal) { // 等号逻辑 ===================num.clear();op.clear();calculate(String.valueOf(showText));refreshText(showText);}else if (v.getId() == R.id.ib_left) { // (refreshText(showText + "(");}else if (v.getId() == R.id.ib_right) { // )refreshText(showText + ")");}else { // 点击了其他按钮,包括数字和小数点refreshText(showText + inputText);}}private void eval() {Double a = num.peek(); num.pop();Double b = num.peek(); num.pop();Character p = op.peek(); op.pop();Double r = 0.0;if(p == '+') r = b + a;if(p == '-') r = b - a;if(p == '*') r = b * a;if(p == '/') r = b / a;num.push(r);}private void calculate(String expression) {while(!num.empty()) num.pop();while(!op.empty()) op.pop();
// System.out.println(expression);for (int i = 0; i < expression.length(); i++) {char c = expression.charAt(i);if (Character.isDigit(c) || c == '.') {Double x = 0.0, k = 0.1;int j = i, z = 0;while (j < expression.length() && (Character.isDigit(expression.charAt(j)) || expression.charAt(j) == '.')) {if(z == 1) {x = x + k * (expression.charAt(j) - '0') * k;k *= 0.1;}if(expression.charAt(j) == '.') {z = 1;}if(z == 0) x = x * 10 + (expression.charAt(j) - '0');j++;}i = j - 1;num.push(x);} else if (c == '(') {op.push(c);} else if (c == ')') {while (op.peek() != '(') eval();op.pop();} else {while (op.size() > 0 && priority[op.peek()] >= priority[c]) eval();op.push(c);}}
// System.out.println(num.size());while (op.size() > 0) eval();if (!num.isEmpty()) {result = String.valueOf(num.pop());refreshText(result);}System.out.println(result);}private void refreshText(String text) {showText = text;tv_result.setText(showText);}private void clear() {num.clear();op.clear();refreshOperate("");refreshText("");}// 刷新运算结果private void refreshOperate(String new_result) {result = new_result;operator = "";}
}
MainActivity3
package com.example.algoritmcalculator;import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;public class MainActivity3 extends AppCompatActivity implements View.OnClickListener {private final static String TAG = "CalculatorActivity";private TextView tv_result; // 声明一个文本视图对象private int operator = 0; // 运算符private int firstNum = 0; // 第一个操作数private int secondNum = 0; // 第二个操作数private int thirdNum = 0; // 第三个操作数private int res = 0;private String result = ""; // 当前的计算结果private String showText = ""; // 显示的文本内容private DatabaseHelper dbhelper;private SQLiteDatabase db;@SuppressLint("MissingInflatedId")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main3);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main3), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});dbhelper = new DatabaseHelper(this);db = dbhelper.getWritableDatabase();addAlgorithm("pow");addAlgorithm("pow_modify");addAlgorithm("is_prime");addAlgorithm("get_prime");addAlgorithm("gcd");addAlgorithm("lcm");addAlgorithm("gauss");addAlgorithm("phi");addAlgorithm("exgcd");findViewById(R.id.one).setOnClickListener(this); // 数字1findViewById(R.id.two).setOnClickListener(this); // 数字2findViewById(R.id.three).setOnClickListener(this); // 数字3findViewById(R.id.four).setOnClickListener(this); // 数字4findViewById(R.id.five).setOnClickListener(this); // 数字5findViewById(R.id.six).setOnClickListener(this); // 数字6findViewById(R.id.seven).setOnClickListener(this); // 数字7findViewById(R.id.eight).setOnClickListener(this); // 数字8findViewById(R.id.nine).setOnClickListener(this); // 数字9findViewById(R.id.zero).setOnClickListener(this); // 数字0findViewById(R.id.pow).setOnClickListener(this);findViewById(R.id.pow_modify).setOnClickListener(this);findViewById(R.id.is_prime).setOnClickListener(this);findViewById(R.id.get_prime).setOnClickListener(this);findViewById(R.id.gcd).setOnClickListener(this);findViewById(R.id.lcm).setOnClickListener(this);findViewById(R.id.gauss).setOnClickListener(this);findViewById(R.id.phi).setOnClickListener(this);findViewById(R.id.exgcd).setOnClickListener(this);findViewById(R.id.equal).setOnClickListener(this);findViewById(R.id.space).setOnClickListener(this);findViewById(R.id.clear).setOnClickListener(this);findViewById(R.id.cancel).setOnClickListener(this);tv_result = findViewById(R.id.textView2);}private void addAlgorithm(String algorithm) {ContentValues values = new ContentValues();values.put("name", algorithm);values.put("count", 0);db.insert("algorithm_usage", null, values);}@Overridepublic void onClick(View v) {String inputText;inputText = ((TextView) v).getText().toString();Log.d(TAG, "inputText=" + inputText);if (v.getId() == R.id.clear) { // 点击了C按钮clear();}else if (v.getId() == R.id.cancel) { // 点击了取消按钮refreshText(showText.substring(0, showText.length() - 1));}else if(v.getId() == R.id.equal) {// 取出操作数对应的字符int ID = operator;dbhelper.incrementAlgorithmCount(ID);if(operator != 7) {calculate(String.valueOf(showText));}else {// 假设 showText 包含输入的所有行// 示例输入:// 3// 1.0 2.0 3.0 4.0// 1.0 2.0 3.0 4.0// 2.0 3.0 4.0 5.0Log.d(TAG, "---------------");Log.d(TAG, "---------------");// 将输入按行分割String[] lines = showText.split("\n");int n = Integer.parseInt(lines[0].trim());for (int i = 0; i <= n; i++) { // 修正循环条件,避免数组越界if(i == 0) Log.d(TAG, String.valueOf(lines[i].charAt(0)));else {for (int j = 0; j < n + 1; j++) { // 使用 i 作为外层循环的索引char c = lines[i].charAt(j); // 获取当前字符Log.d(TAG, String.valueOf(c)); // 修正日志打印语法}}}// 获取行数 n,这里是输入的第一个数MathUtils.a = new double[n + 5][n + 5]; // 下标从 0 开始
// 处理每一行数据,从第二行开始for (int i = 1; i <= n; i++) {// 将每一行按空格分割String[] values = lines[i].trim().split("\\s+");for (int j = 0; j < n + 1; j++) {
// 将值存储到 MathUtils.a 中MathUtils.a[i - 1][j] = Double.parseDouble(values[j]); // i - 1 是因为数组下标从 0 开始}}Log.d(TAG, "0000000000");Log.d(TAG, String.valueOf(n));for(int i = 0; i < n; i++) {for(int j = 0; j < n + 1; j++) {Log.d(TAG, String.valueOf(MathUtils.a[i][j]));}}// 执行高斯消元法int z = MathUtils.gauss(n);if (z == 2) { // 无解showText = "No solution";} else if (z == 1) { // 有无穷多组解showText = "Infinite solutions";} else { // 有唯一解,显示 a 数组的第一行StringBuilder result = new StringBuilder();for (int j = 0; j < n; j++) {result.append(MathUtils.a[j][n]).append(" ");System.out.println(MathUtils.a[j][n]);}
// result.append(MathUtils.a[0][n]); // 假设最后一列是解showText = result.toString();}for(int i = 0; i < n; i++) {for(int j = 0; j < n + 1; j++) {Log.d(TAG, "=======");Log.d(TAG, String.valueOf(MathUtils.a[i][j]));}}}refreshText(showText);}else if(v.getId() == R.id.pow) operator = 1;else if(v.getId() == R.id.pow_modify) operator = 2;else if(v.getId() == R.id.is_prime) operator = 3;else if(v.getId() == R.id.get_prime) operator = 4;else if(v.getId() == R.id.gcd) operator = 5;else if(v.getId() == R.id.lcm) operator = 6;else if(v.getId() == R.id.gauss) {if(operator == 7) {showText = showText + "\n";}operator = 7;}else if(v.getId() == R.id.phi) operator = 8;else if(v.getId() == R.id.exgcd) operator = 9;else if(v.getId() == R.id.linear) operator = 10;else { // 点击了其他按钮,包括数字和小数点refreshText(showText + inputText);}
// refreshText(showText + inputText);}private void calculate(String expression) {int z = 0;for (int i = 0; i < expression.length(); i++) {char c = expression.charAt(i);if (Character.isDigit(c)) {int x = 0;int j = i;while (j < expression.length() && Character.isDigit(expression.charAt(j))) {x = x * 10 + (expression.charAt(j) - '0');j++;}i = j - 1;if(z == 0) {firstNum = x;z = 1;}else if(z == 1) {secondNum = x;z = 2;}else {thirdNum = x;z = 0;}}}switch(operator) {case 1:res = MathUtils.qmi(firstNum, secondNum);break;case 2:res = MathUtils.qm(firstNum, secondNum, thirdNum);break;case 3:boolean isPrime = MathUtils.is_prime(firstNum);result = isPrime ? "Prime" : "Not Prime";break;case 4:MathUtils.get_prime(firstNum);// Assuming you want to display the primes in some wayStringBuilder primesBuilder = new StringBuilder();for (int j = 0; j < MathUtils.cnt; j++) {primesBuilder.append(MathUtils.primes[j]).append(" ");}result = primesBuilder.toString();break;case 5:res = MathUtils.gcd(firstNum, secondNum);break;case 6:res = MathUtils.lcm(firstNum, secondNum);break;//case 7:// gauss function is not implementedcase 8:res = MathUtils.phi(firstNum);break;case 9: {int[] x = new int[1];int[] y = new int[1];MathUtils.exgcd(firstNum, secondNum, x, y);res = x[0]; // or y[0] depending on what you want to returnbreak;}case 10: {int[] x = new int[1];int[] y = new int[1];long d = MathUtils.linear(firstNum, secondNum, x, y);res = (int)d; // or x[0] or y[0] depending on what you want to returnbreak;}default:Toast.makeText(this, "Invalid operation", Toast.LENGTH_SHORT).show();return;}// Display the resultif (operator != 3 && operator != 4 && operator != 10 && operator != 9) {result = String.valueOf(res);}refreshText(result);}// 刷新文本显示private void refreshText(String text) {showText = text;CharSequence t = showText;Log.d(TAG, "t=" + t);tv_result.setText(t);}// 清空并初始化private void clear() {//refreshOperate("");refreshText("");operator = 0;}}
MainActivity4
package com.example.algoritmcalculator;import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ListView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import android.widget.TextView;
import java.util.List;public class MainActivity4 extends AppCompatActivity {private DatabaseHelper dbHelper; // 声明 dbHelper 为类的成员变量private ListView listView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main4);dbHelper = new DatabaseHelper(this); // 初始化 dbHelperViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main4), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});Button openWebButton = findViewById(R.id.openWebButton);openWebButton.setOnClickListener(view -> {Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("https://blog.csdn.net/lxy___lxy/article/details/143371873?spm=1001.2014.3001.5502"));startActivity(intent);});// 获取算法使用次数List<Integer> counts = dbHelper.getAlgorithmCounts();// 更新TextView的文本updateTextViews(counts);}private void updateTextViews(List<Integer> counts) {TextView textView1 = findViewById(R.id.algorithm1_count);TextView textView2 = findViewById(R.id.algorithm2_count);TextView textView3 = findViewById(R.id.algorithm3_count);TextView textView4 = findViewById(R.id.algorithm4_count);TextView textView5 = findViewById(R.id.algorithm5_count);TextView textView6 = findViewById(R.id.algorithm6_count);TextView textView7 = findViewById(R.id.algorithm7_count);TextView textView8 = findViewById(R.id.algorithm8_count);TextView textView9 = findViewById(R.id.algorithm9_count);textView1.setText(String.valueOf(counts.get(0)));textView2.setText(String.valueOf(counts.get(1)));textView3.setText(String.valueOf(counts.get(2)));textView4.setText(String.valueOf(counts.get(3)));textView5.setText(String.valueOf(counts.get(4)));textView6.setText(String.valueOf(counts.get(5)));textView7.setText(String.valueOf(counts.get(6)));textView8.setText(String.valueOf(counts.get(7)));textView9.setText(String.valueOf(counts.get(8)));}
}
MathUtils
package com.example.algoritmcalculator;public class MathUtils {public static boolean[] st = new boolean[100000];public static int[] primes = new int[100000];public static int cnt;public static double[][] a = new double[100][100];// 为二维数组赋值的方法public void initializeMatrix(double[][] values) {if (values.length != a.length || values[0].length != a[0].length) {throw new IllegalArgumentException("初始化数组的维度与a[][]不匹配");}for (int i = 0; i < a.length; i++) {System.arraycopy(values[i], 0, a[i], 0, a[i].length);}}public static int qmi(int a, int k) {int res = 1;while (k != 0) {if ((k & 1) != 0) res = res * a;k >>>= 1; // 使用无符号右移,确保位移操作的正确性a = a * a; // 将a扩大平方倍}return res;}public static int qm(int a, int b, int p) {int res = 1;while (b != 0) {if ((b & 1) != 0) res = (res * a) % p;a = (a * a) % p;b >>= 1;}return res;}public static boolean is_prime(int x) {if (x < 2) return false;for (int i = 2; i <= x / i; i++) {if (x % i == 0) return false;}return true;}public static void get_prime(int n) {for (int i = 2; i <= n; i++) {if (!st[i]) primes[cnt++] = i;for (int j = 0; primes[j] <= n / i; j++) {st[primes[j] * i] = true;if (i % primes[j] == 0) break;}}}public static int gcd(int a, int b) {return b != 0 ? gcd(b, a % b) : a;}public static int lcm(int a, int b) {return a * b / gcd(a, b);}private static void swapRows(int row1, int row2) {double[] temp = a[row1];a[row1] = a[row2];a[row2] = temp;}public static int gauss(int n) {double EPSILON = 1e-6;int c, r;for (c = 0, r = 0; c < n; c++) {int t = r;for (int i = r; i < n; i++) { // 找出绝对值最大的行if (Math.abs(a[i][c]) > Math.abs(a[t][c])) t = i;}if (Math.abs(a[t][c]) < EPSILON) continue;for(int i = c; i <= n; i ++ ) {// 将绝对值最大的行换到最顶端double w = a[t][i];a[t][i] = a[r][i];a[r][i] = w;}for(int i = n; i >= c; i -- ) a[r][i] /= a[r][c]; // 将当前行的首位变成1for (int i = r + 1; i < n; i++) { // 用当前行将下面所有的列消成0if (Math.abs(a[i][c]) > EPSILON) {for (int j = n; j >= c; j--) {a[i][j] -= a[r][j] * a[i][c];}}}r++;}if (r < n) {for (int i = r; i < n; i++) {if (Math.abs(a[i][n]) > EPSILON) return 2; // 无解,即b不为0}return 1; // 有无穷多组解}for (int i = n - 1; i >= 0; i--) {for (int j = i + 1; j < n; j++) {a[i][n] -= a[i][j] * a[j][n];}}return 0; // 有唯一解}public static int phi(int x) {int res = x;for (int i = 2; i <= x / i; i++) {if (x % i == 0) {res = res / i * (i - 1);while (x % i == 0) x /= i;}}if (x > 1) res = res / x * (x - 1);return res;}public static void exgcd(int a, int b, int[] x, int[] y) {if (b == 0) {x[0] = 1;y[0] = 0;return;}int aa = a, bb = b;MathUtils.exgcd(bb, aa % bb, y, x);y[0] = y[0] - (a / b) * x[0];}public static int linear(int a, int b, int[] x, int[] y) {if (b == 0) {x[0] = 1;y[0] = 0;return a;}int d = MathUtils.linear(b, a % b, y, x);y[0] -= a / b * x[0];return d;}
}
xml代码
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="16dp"><EditTextandroid:id="@+id/passwordEditText"android:layout_width="500dp"android:layout_height="50dp"android:hint="Enter Password"android:inputType="textPassword"android:layout_centerInParent="true" /><Buttonandroid:id="@+id/loginButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Login"android:layout_below="@id/passwordEditText"android:layout_centerHorizontal="true"android:layout_marginTop="16dp" /></RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.constraintlayout.widget.Groupandroid:id="@+id/group"android:layout_width="wrap_content"android:layout_height="wrap_content" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center_horizontal"android:background="#2CC0F1"><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="计算器"android:textSize="60dp"tools:layout_editor_absoluteX="50dp"tools:layout_editor_absoluteY="15dp" /><Buttonandroid:id="@+id/button"android:layout_width="300dp"android:layout_height="120dp"android:layout_marginTop="50sp"android:text="普通计算器"android:background="#8ed1c0"android:textSize="30sp"tools:layout_editor_absoluteX="84dp"tools:layout_editor_absoluteY="372dp" /><Buttonandroid:id="@+id/button2"android:layout_width="300dp"android:layout_height="120dp"android:text="算法计算器"android:background="#ce8ed1"android:textSize="30sp"android:layout_marginTop="50sp"tools:layout_editor_absoluteX="84dp"tools:layout_editor_absoluteY="213dp" /><Buttonandroid:id="@+id/button3"android:layout_width="300dp"android:layout_height="120dp"android:text="使用模块"android:background="#7766"android:textSize="30sp"android:layout_marginTop="50sp"tools:layout_editor_absoluteX="84dp"tools:layout_editor_absoluteY="213dp" /></LinearLayout></androidx.constraintlayout.widget.ConstraintLayout>
activity_main2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/main2"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity2"android:background="#eeeeee"android:orientation="vertical"android:padding="5dp"><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:layout_width="360dp"android:layout_height="wrap_content"android:gravity="center"android:text="计算器"android:textColor="#000000"android:textSize="20sp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/tv_result"android:layout_width="360dp"android:layout_height="wrap_content"android:background="#ffffff"android:gravity="right|bottom"android:lines="3"android:maxLines="3"android:scrollbars="vertical"android:text="0"android:textColor="#000000"android:textSize="25sp" /></LinearLayout><GridLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:columnCount="4"><Buttonandroid:id="@+id/btn_cancel"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="CE"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_divide"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="/"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_multiply"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="*"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_clear"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="C"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_seven"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="7"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_eight"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="8"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_nine"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="9"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_plus"android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center"android:text="+"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_four"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="4"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_five"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="5"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_six"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="6"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_minus"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="-"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_one"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="1"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_two"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="2"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_three"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="3"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_equal"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="="android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_dot"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="."android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_zero"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="0"android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/ib_left"android:layout_width="90dp"android:layout_height="75dp"android:gravity="center"android:text="("android:textColor="@color/black"android:textSize="30sp" /><Buttonandroid:id="@+id/ib_right"android:layout_width="89dp"android:layout_height="75dp"android:gravity="center"android:text=")"android:textColor="@color/black"android:textSize="30sp" /></GridLayout></LinearLayout></ScrollView></LinearLayout>
activity_main3.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/main3"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity3"><TextViewandroid:id="@+id/textView2"android:layout_width="match_parent"android:layout_height="139dp"android:layout_margin="10sp"android:text="TextView"android:textSize="30sp" /><GridLayoutandroid:layout_width="match_parent"android:layout_height="550sp"android:columnCount="4"android:layout_margin="10sp"android:rowCount="5"><Buttonandroid:id="@+id/pow"android:layout_width="0dp"android:layout_height="0dp"android:layout_rowWeight="1"android:layout_margin="5sp"android:layout_columnWeight="1"android:background="#FFB1CD"android:text="pow" /><Buttonandroid:id="@+id/pow_modify"android:layout_width="0dp"android:layout_height="0dp"android:layout_rowWeight="1"android:layout_margin="5sp"android:layout_columnWeight="1"android:background="#FFB1CD"android:text="pow_modify" /><Buttonandroid:id="@+id/is_prime"android:layout_width="0dp"android:layout_height="0dp"android:layout_rowWeight="1"android:layout_margin="5sp"android:layout_columnWeight="1"android:background="#FFB1CD"android:text="is_prime" /><Buttonandroid:id="@+id/get_prime"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:layout_rowWeight="1"android:layout_columnWeight="1"android:background="#FFB1CD"android:text="get_prime" /><Buttonandroid:id="@+id/gcd"android:layout_width="0dp"android:layout_height="0dp"android:layout_rowWeight="1"android:layout_columnWeight="1"android:layout_margin="5sp"android:background="#FFB1CD"android:text="gcd" /><Buttonandroid:id="@+id/lcm"android:layout_width="0dp"android:layout_height="0dp"android:layout_rowWeight="1"android:layout_columnWeight="1"android:layout_margin="5sp"android:background="#FFB1CD"android:text="lcm" /><Buttonandroid:id="@+id/gauss"android:layout_width="0dp"android:layout_height="0dp"android:layout_rowWeight="1"android:layout_columnWeight="1"android:layout_margin="5sp"android:background="#FFB1CD"android:text="gauss" /><Buttonandroid:id="@+id/phi"android:layout_width="0dp"android:layout_height="0dp"android:background="#FFB1CD"android:layout_rowWeight="1"android:layout_columnWeight="1"android:layout_margin="5sp"android:text="phi" /><Buttonandroid:id="@+id/exgcd"android:layout_width="0dp"android:background="#FFB1CD"android:layout_height="0dp"android:layout_margin="5sp"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="exgcd" /><Buttonandroid:id="@+id/linear"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:background="#FFB1CD"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="linear" /><Buttonandroid:id="@+id/cancel"android:layout_width="0dp"android:layout_height="0dp"android:background="#95A3F7"android:layout_margin="5sp"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="CE" /><Buttonandroid:id="@+id/clear"android:layout_width="0dp"android:background="#95A3F7"android:layout_margin="5sp"android:layout_height="0dp"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="C" /><Buttonandroid:id="@+id/one"android:layout_width="0dp"android:background="#8ebed1"android:layout_height="0dp"android:layout_margin="5sp"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="1" /><Buttonandroid:id="@+id/two"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:layout_rowWeight="1"android:layout_columnWeight="1"android:background="#8ebed1"android:text="2" /><Buttonandroid:id="@+id/three"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:layout_rowWeight="1"android:background="#8ebed1"android:layout_columnWeight="1"android:text="3" /><Buttonandroid:id="@+id/zero"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:layout_rowWeight="1"android:background="#8ebed1"android:layout_columnWeight="1"android:text="0" /><Buttonandroid:id="@+id/four"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:background="#8ebed1"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="4" /><Buttonandroid:id="@+id/five"android:layout_width="0sp"android:layout_height="0sp"android:layout_margin="5sp"android:layout_rowWeight="1"android:background="#8ebed1"android:layout_columnWeight="1"android:text="5" /><Buttonandroid:id="@+id/six"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:background="#8ebed1"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="6" /><Buttonandroid:id="@+id/space"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:background="#8ebed1"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text=" " /><Buttonandroid:id="@+id/seven"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:background="#8ebed1"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="7" /><Buttonandroid:id="@+id/eight"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:background="#8ebed1"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="8" /><Buttonandroid:id="@+id/nine"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:layout_rowWeight="1"android:background="#8ebed1"android:layout_columnWeight="1"android:text="9" /><Buttonandroid:id="@+id/equal"android:layout_width="0dp"android:layout_height="0dp"android:layout_margin="5sp"android:background="#d1908e"android:layout_rowWeight="1"android:layout_columnWeight="1"android:text="=" /></GridLayout></LinearLayout>
activity_main4.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/main4"android:layout_width="match_parent"android:layout_height="match_parent"><!-- 超链接按钮,位于右上角 --><Buttonandroid:id="@+id/openWebButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="使用说明"app:layout_constraintTop_toTopOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_margin="16dp" /><!-- 表格布局 --><TableLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:stretchColumns="*"app:layout_constraintTop_toBottomOf="@id/openWebButton"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"><!-- 表头 --><TableRow><TextViewandroid:layout_column="0"android:gravity="center"android:padding="8dp"android:text="Algorithm Name" /><TextViewandroid:text="Usage Count"android:gravity="center"android:padding="8dp"android:layout_column="1" /></TableRow><!-- 算法1 --><TableRow><TextViewandroid:text="pow"android:gravity="center"android:padding="8dp" /><TextViewandroid:text="0"android:id="@+id/algorithm1_count"android:gravity="center"android:padding="8dp" /></TableRow><!-- 算法2 --><TableRow><TextViewandroid:text="pow_modify"android:gravity="center"android:padding="8dp" /><TextViewandroid:text="0"android:id="@+id/algorithm2_count"android:gravity="center"android:padding="8dp" /></TableRow><!-- 算法3 --><TableRow><TextViewandroid:text="is_prime"android:gravity="center"android:padding="8dp" /><TextViewandroid:text="0"android:id="@+id/algorithm3_count"android:gravity="center"android:padding="8dp" /></TableRow><!-- 算法4 --><TableRow><TextViewandroid:text="get_prime"android:gravity="center"android:padding="8dp" /><TextViewandroid:text="0"android:id="@+id/algorithm4_count"android:gravity="center"android:padding="8dp" /></TableRow><!-- 算法5 --><TableRow><TextViewandroid:text="gcd"android:gravity="center"android:padding="8dp" /><TextViewandroid:text="0"android:id="@+id/algorithm5_count"android:gravity="center"android:padding="8dp" /></TableRow><!-- 算法6 --><TableRow><TextViewandroid:text="lcm"android:gravity="center"android:padding="8dp" /><TextViewandroid:text="0"android:id="@+id/algorithm6_count"android:gravity="center"android:padding="8dp" /></TableRow><!-- 算法7 --><TableRow><TextViewandroid:text="gauss"android:gravity="center"android:padding="8dp" /><TextViewandroid:text="0"android:id="@+id/algorithm7_count"android:gravity="center"android:padding="8dp" /></TableRow><!-- 算法8 --><TableRow><TextViewandroid:text="phi"android:gravity="center"android:padding="8dp" /><TextViewandroid:text="0"android:id="@+id/algorithm8_count"android:gravity="center"android:padding="8dp" /></TableRow><!-- 算法9 --><TableRow><TextViewandroid:text="exgcd"android:gravity="center"android:padding="8dp" /><TextViewandroid:text="0"android:id="@+id/algorithm9_count"android:gravity="center"android:padding="8dp" /></TableRow></TableLayout></androidx.constraintlayout.widget.ConstraintLayout>
四、使用函数介绍
POW:
输入:两个整数,空格隔开(底数, 指数)
点击POW按钮后按等号计算(其余函数不再赘述)
读入底数和指数,通过快速幂算法求出值
bool is_prime(int x){if(x < 2) return false;for(int i = 2; i <= x / i; i ++ ){if(x % i == 0) return false;}return true;
}
POW_MODIFY:
输入:三个整数,空格隔开(底数,指数,求余mod)
逆元:除以一个数求余等于乘上这个逆元再求余
【由于求余法则中没有除法的规定,我们只能通过逆元来求余】
乘法逆元的定义
若整数 b,m 互质,并且对于任意的整数 a,如果满足 b|a,则存在一个整数 x,使得 a/b≡a×x(mod m),则称 x 为 b 的模 m 乘法逆元,记为 b−1(mod m)。
b 存在乘法逆元的充要条件是 b 与模数 m 互质。当模数 m 为质数时,b^m−2即为 b 的乘法逆元。
由此可知,求逆元的方式同快速幂,只需要将指数改为p-2即可
ll qm(ll a, ll b, ll p)
{ll res = 1;while(b){if(b & 1) res = res * a % p;a = a * a % p;b >>= 1;}return res;
}
IS_PRIME:
输入:一个整数(判断是否为质数)
输入一个数,判断是否为质数,质数返回√,非质数返回×
bool is_prime(int x){if(x < 2) return false;for(int i = 2; i <= x / i; i ++ ){if(x % i == 0) return false;}return true;
}
GET_PRIME:
输入:一个整数(输出小于它的所有质数)
输入一个数,筛出1~n中的质数,输出为数组,采用线性筛
bool st[N];
int primes[N], cnt;void get_prime(int n){for(int i = 2; i <= n; i++){if(!st[i]) primes[cnt ++ ] = i;for(int j = 0; primes[j] <= n / i; j ++ ){st[primes[j] * i] = true;if(i % primes[j] == 0) break;}}
}
GCD:
输入:两个整数(输出其最大公约数)
输入两个数,输出最大公约数,采用辗转相除法
int gcd(int a, int b) {return b ? gcd(b, a % b) : a; // 辗转相除法
}
LCM:
输入:两个整数(输出其最小公倍数)
输入两个数,输出最小公倍数
int lcm(int a, int b) {return a * b / gcd(a, b);
}
GAUSS:
输入:一个n,接下来n行代表着输入的未知数常数(输出为各个未知数)
输入常数,输出所有xi的值
int gauss() // 高斯消元
{int c, r;for(c = 0, r = 0; c < n; c ++ ){int t = r;for(int i = r; i < n; i ++ ) // 找出绝对值最大的行{if(fabs(a[i][c]) > fabs(a[t][c])) t = i;}if(fabs(a[t][c]) < eps) continue;for(int i = c; i <= n; i ++ ) swap(a[t][i], a[r][i]); // 将绝对值最大的行换到最顶端for(int i = n; i >= c; i -- ) a[r][i] /= a[r][c]; // 将当前行的首位变成1for(int i = r + 1; i < n; i ++ ) // 用当前行将下面所有的列消成0{if(fabs(a[i][c]) > eps){for(int j = n; j >= c; j -- ){a[i][j] -= a[r][j] * a[i][c];}}}r ++ ;}if(r < n){for(int i = r; i < n; i ++ ){if(fabs(a[i][n]) > eps) return 2; // 无解,即b不为0}return 1; // 有无穷多组解}for(int i = n - 1; i >= 0; i -- ){for(int j = i + 1; j < n; j ++ ){a[i][n] -= a[i][j] * a[j][n];}}return 0;
}
PHI:
输入:一个整数(输出其欧拉函数)
欧拉函数:1~N中与N互质的数的个数被称为欧拉函数,记为 ϕ(N)。
公式: phi = 质数分之质数-1之积
思路: 通过试除法找到质数,然后套用公式
int phi(int x) {int res = x;for(int i = 2; i <= x / i; i++) {if(x % i == 0) {res = res / i * (i - 1);while(x % i == 0) x /= i;}}if(x > 1) res = res / x * (x - 1);return res;
}
EXGCD:
输入:两个整数a,b(输出为x,y的值)
扩展欧几里得算法:求出一组x,y,使得a * x + b * y == gcd(a, b)
void exgcd(int a, int b, int &x, int &y) {if(!b) {x = 1, y = 0;return ;}exgcd(b, a % b, y, x);y = y - a / b * x;
}
LINEAR:
输入:两个整数a,b(输出x)
线性同余方程:求一个x,满足a * x == b(mod m)
#include<iostream>
#include<algorithm>using namespace std;typedef long long ll;ll linear(ll a, ll b, ll &x, ll &y)
{if(!b){x = 1, y = 0; // 边界,(或理解为递归的重点)return a;}int d = linear(b, a % b, y, x);// y与b对应,x与a对应y -= a / b * x;// 公式推导return d;
}int main()
{int n;cin >> n;while(n -- ){ll a, b, m;cin >> a >> b >> m;ll x, y;ll t = linear(a, m, x, y);if(b % t) puts("impossible");else cout << x * (b / t) % m << endl;}return 0;
}
尾言
随便写写,此处并不重要
创作原因: 其实很早以前就想做一个可以随时使用的算法计算器了,特别是大一的时候,哪个时候学C语言嘛,然后又要经常做题,什么闰年判断呀,质数,公约数,公倍数啥的一堆堆,但是不会啊,然后常常去搜一个数是不是闰年,从1-1000有多少质数等等,于是那个时候想的是如果有一个程序,可以直接执行我想要搜的东西去验证我的代码结果和正确答案是不是一样的就好啦,然后学习算法之后,会的算法也越来越多,接触到的算法也越来越复杂,也正好趁着这次课设的时间,去完成一个稍微不那么美观但是能够用的计算器,虽然现在真正可能也用不到了,哈哈哈,但是得到老师许可后可以当课设来写,还是感到很开心的,把之前的简陋版本完善了,然后新加了一堆堆~没有什么用处的辅助功能,让它看起来像一个靠谱的课设结果。