Apache Commons Math3库实战使用指南

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:Apache Commons Math是一个Java科学计算库,提供丰富的数学和统计功能,支持复杂数学运算。版本3.6包含多种数学组件,如基本数学操作、随机数生成、线性代数处理、数值方法、统计分析、特殊函数、优化算法、序列处理及组合数学。它在科学计算、数据分析、机器学习等多个领域得到广泛应用,简化了开发过程,提升了代码质量和效率。 commons-math3-3.6.zip

1. Apache Commons Math库概述

Apache Commons Math库是一个开源的Java库,用于解决常见的数学和统计问题。它提供了丰富的数学函数、概率分布、数值方法、统计分析工具、优化算法、特殊数学函数、序列和数列处理、组合数学计算等多种数学操作,极大地简化了这些复杂计算过程。无论是简单的数值运算还是复杂的数学模型构建,Commons Math都能提供高效的解决方案。

在本章中,我们将深入了解Apache Commons Math库的基础知识和核心功能,带领读者快速入门并掌握其使用方法,为深入学习后续章节做好准备。

1.1 数学库的必要性

在开发过程中,经常会遇到需要处理数学计算的场景,如进行矩阵运算、统计分析、数值计算、概率分析等。传统的做法是手写算法,不仅耗时耗力,而且容易出错。Apache Commons Math库作为一个成熟的数学工具库,提供了经过严格测试的大量数学计算功能,让开发者可以专注于业务逻辑的实现,极大地提高了开发效率和代码的可靠性。

1.2 安装和配置

Apache Commons Math库并不是Java标准库的一部分,因此在使用前需要将其添加到项目依赖中。对于使用Maven的项目,可以在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>***mons</groupId>
    <artifactId>commons-math3</artifactId>
    <version>3.6.1</version> <!-- 请检查最新的版本号 -->
</dependency>

对于不使用构建工具的项目,需要手动下载jar文件并将其添加到项目的类路径中。

1.3 简单示例

下面是一个简单的示例,演示如何使用Apache Commons Math库计算两个数的和:

``` mons.math3.util.ArithmeticUtils;

public class MathExample { public static void main(String[] args) { int a = 10; int b = 20; int sum = ArithmeticUtils.add(a, b); System.out.println("The sum of " + a + " and " + b + " is " + sum); } }


此代码展示了如何将Apache Commons Math库中的`ArithmeticUtils`类用于执行基本的数值加法操作。这只是库提供的众多功能的一个小例子,随着后续章节的深入,我们将探索更多高级功能和使用场景。

# 2. 基础数学功能

## 2.1 数值计算基础

### 2.1.1 数值类型概述

在进行数值计算时,首先要了解Apache Commons Math库提供的数值类型。Apache Commons Math库支持多种数值类型,包括但不限于整数、浮点数、复数等。在不同场景下选择合适的数值类型能够提高计算精度和效率。

整数类型例如`BigInteger`和`BigDecimal`,它们能够处理超出Java原生类型限制的大整数和高精度的小数运算。特别是对于涉及大量计算和精确货币运算的场景,这两个类是必不可少的。

浮点数计算可以使用Java自带的`float`和`double`类型,然而当涉及到更高精度的浮点运算时,Apache Commons Math提供了`Real`接口及其实现类,这些类封装了复杂数值运算的细节,使得用户可以方便地进行高精度计算。

### 2.1.2 基本数学运算接口

接下来是基本数学运算的接口,这些接口定义了各种数学运算的抽象方法,包括加、减、乘、除等。接口的实现类可以根据具体需求进行扩展和优化,如优化算法实现,提升性能等。

例如,`MathTransform`接口定义了一种可以在数学空间之间进行转换的运算。其具体实现包括`FFT`类(快速傅里叶变换)、`DCT`类(离散余弦变换)等,这些变换在信号处理、图像处理等领域有着广泛的应用。

## 2.2 数学常量和基本函数

### 2.2.1 数学常量的定义与应用

数学常量是数学计算中经常使用的值,例如π(圆周率)、e(自然对数的底数)等。在Apache Commons Math库中,这些常量被精确地定义,并可以在各种计算中使用。

应用这些数学常量时,通常只需要调用库提供的预定义接口,如`MathUtils.PI`和`MathUtils.E`。这些接口封装了常量的定义,用户无需记住具体的数值就能轻松调用。

### 2.2.2 常用数学函数及其使用

除了数学常量,Apache Commons Math库还提供了大量常用的数学函数,包括三角函数、对数函数、指数函数等。这些函数是数值计算中不可或缺的工具,能够处理各种复杂的数学问题。

函数的使用非常简单。以三角函数为例,可以使用`TrigonometryUtils`类中的方法来获取角度或弧度制下的正弦、余弦、正切值。

```***
***mons.math3.util.FastMath;

double angle = 60; // 角度制
double radian = FastMath.toRadians(angle); // 转换为弧度制
double sinValue = FastMath.sin(radian); // 计算正弦值

以上代码展示了如何在Apache Commons Math库中计算一个角度的正弦值。 FastMath 类提供了各种基本数学函数的实现,使用时要注意输入值的单位和期望的输出值。

在实际应用中,对于非标准的数学函数或特殊数学运算需求,Apache Commons Math也提供了扩展接口和自定义实现的途径,使得库的使用更加灵活和强大。

3. 随机数和概率分布

3.1 随机数生成器

3.1.1 随机数生成器的类型

在进行模拟、优化算法或其他需要随机性输入的场景中,随机数生成器是不可或缺的组件。Apache Commons Math库提供了多种类型的随机数生成器,每种生成器都有其特定的用途和特点。

  • Pseudo-random number generators (PRNGs) : 伪随机数生成器是基于数学算法的,可以产生看似随机的序列,但实际上是确定性的。它们适用于大多数模拟应用,因为它们足够“随机”且效率高。PRNGs在初始化时通常需要一个种子值,相同的种子会产生相同的随机数序列,这在需要重复实验时非常有用。

  • Cryptographically secure pseudo-random number generators (CSPRNGs) : 这类生成器的随机数序列不仅看起来随机,而且还能通过密码学标准的安全性测试。与常规PRNGs相比,它们在保护数据安全方面表现更好,比如用于密钥生成、一次性密码本等。

3.1.2 随机数生成器的选择与应用

选择合适的随机数生成器对于确保随机性质量和程序性能至关重要。例如,如果应用需要符合密码学安全标准,那么CSPRNG是必要的选择。而当模拟运行需要可复现性时,使用具有固定种子的PRNG会是更好的选择。

一个典型的PRNG使用示例如下:

``` mons.math3.random.JDKRandomGenerator;

public class RandomNumberGeneratorExample { public static void main(String[] args) { // 创建一个基于JDK的随机数生成器实例 JDKRandomGenerator rng = new JDKRandomGenerator(); // 设置种子(这一步可以根据需要省略,系统会自动提供种子) rng.setSeed(42L); // 生成随机数 int randomInt = rng.nextInt(); double randomDouble = rng.nextDouble(); System.out.println("Random Integer: " + randomInt); System.out.println("Random Double: " + randomDouble); } }


在这个示例中,`JDKRandomGenerator` 被设置了一个种子值 `42`,这意味着每次运行代码时产生的随机数序列将保持一致。通过调用 `nextInt()` 和 `nextDouble()` 方法,分别生成了整数和双精度浮点数类型的随机数。

## 3.2 概率分布模型

### 3.2.1 离散和连续概率分布

在概率论和统计学中,概率分布是对随机变量可能取值及其发生概率的一种描述。Apache Commons Math库支持各种概率分布,并提供了丰富的接口来处理它们。

- **离散概率分布**: 包括伯努利分布、二项分布、泊松分布等。离散随机变量的取值是有限或可数无限的,例如,抛硬币的结果或某地区的人口数。

- **连续概率分布**: 包括正态分布、指数分布、均匀分布等。连续随机变量可以取任何值,通常在某个区间内,例如测量误差或人的身高。

### 3.2.2 分布参数的设定与使用

每种概率分布都有其特定的参数,这些参数定义了分布的形状和特征。例如,正态分布由均值(mean)和标准差(standard deviation)来定义;二项分布由试验次数(n)和成功概率(p)来定义。

在Apache Commons Math中,可以通过特定分布的类来创建概率分布实例,并进行概率计算。下面是一个正态分布的示例:

```***
***mons.math3.distribution.NormalDistribution;
***mons.math3.stat.descriptive.UnivariateStatistic;
***mons.math3.stat.descriptive.summary.Sum;

public class ProbabilityDistributionExample {
    public static void main(String[] args) {
        // 创建正态分布实例,均值为0.0,标准差为1.0
        NormalDistribution normalDist = new NormalDistribution(0.0, 1.0);
        // 计算并打印概率密度函数(PDF)的值
        double pdfValue = normalDist.density(0.5);
        System.out.println("PDF value at 0.5: " + pdfValue);
        // 使用统计描述符进行描述统计
        UnivariateStatistic sum = new Sum();
        double sumOfValues = sum.evaluate(normalDist.sample(1000));
        System.out.println("Sum of sampled values: " + sumOfValues);
    }
}

在这个代码中,我们创建了一个均值为0、标准差为1的正态分布实例。使用 density 方法来计算随机变量值为0.5时的概率密度。另外,我们使用了 Sum 类来计算采样值的总和,这是描述统计中的一个应用。

概率分布的使用不仅限于理论计算,它在实际问题的建模和解决中具有广泛的应用,如在风险评估、质量控制和信号处理等领域。通过Apache Commons Math库,可以更方便地实现这些计算。

4. 线性代数操作

4.1 向量和矩阵的操作

向量和矩阵是线性代数中最基本的两个概念,它们在数据表示和计算中起着重要的作用。了解并熟练使用Apache Commons Math库中提供的向量和矩阵操作,对于处理更复杂的数学问题具有至关重要的意义。

4.1.1 向量和矩阵的创建与表示

在Apache Commons Math中,向量通常用 RealVector 接口表示,而矩阵则用 RealMatrix 接口。库提供了多种方式来创建向量和矩阵,例如直接从数组初始化,或者通过构建器模式(Builder pattern)动态创建。

``` mons.math3.linear.*;

// 创建一个3维的RealVector向量 RealVector vector = new ArrayRealVector(new double[]{1.0, 2.0, 3.0});

// 创建一个3x3的RealMatrix矩阵 RealMatrix matrix = new Array2DRowRealMatrix(new double[][]{ {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0} });


**参数说明:**
- `ArrayRealVector` 和 `Array2DRowRealMatrix`:分别是向量和矩阵的具体实现,用于表示具有数组形式的数据结构。
- 构造函数中的二维数组:对于矩阵,每一行代表一个数据数组,矩阵是行主序(row-major order)存储。

#### 4.1.2 向量和矩阵的基本运算

一旦创建了向量和矩阵,就可以执行各种数学运算。这包括加法、减法、标量乘法、向量点积、矩阵乘法等。

```java
// 向量加法
RealVector vector2 = new ArrayRealVector(new double[]{4.0, 5.0, 6.0});
RealVector sumVector = vector.add(vector2);

// 矩阵乘法
RealMatrix matrix2 = new Array2DRowRealMatrix(new double[][]{
    {1.0, 1.0},
    {0.0, 1.0},
    {0.0, 0.0}
});
RealMatrix productMatrix = matrix.multiply(matrix2);

// 向量点积
double dotProduct = vector.dotProduct(vector2);

参数说明: - add multiply 方法:分别为执行向量和矩阵的加法和乘法。 - dotProduct 方法:用来计算两个向量的点积。

4.2 线性方程组求解

线性方程组是数学和工程问题中的常见形式,Apache Commons Math提供了多种方式来求解线性方程组。

4.2.1 方程组求解方法概述

求解线性方程组的方法主要分为两大类:直接法和迭代法。直接法可以提供精确解,但可能对矩阵条件数较为敏感;而迭代法通常用于大型矩阵,能够容忍一定的计算误差。

4.2.2 实际案例演示

假设我们有如下线性方程组:

x + 2y + 3z = 6
2x + 5y + 3z = 9
3x + 3y + 2z = 8

我们可以使用Apache Commons Math中的 LUDecomposition 类求解这个方程组:

// 定义系数矩阵和常数项向量
RealMatrix matrix = new Array2DRowRealMatrix(new double[][]{
    {1.0, 2.0, 3.0},
    {2.0, 5.0, 3.0},
    {3.0, 3.0, 2.0}
});
RealVector vector = new ArrayRealVector(new double[]{6.0, 9.0, 8.0});

// 使用LU分解求解线性方程组
LUDecomposition lu = new LUDecomposition(matrix);
RealVector solution = lu.solve(vector);

参数说明: - LUDecomposition : LU分解是一种矩阵分解技术,可以将一个矩阵分解为一个下三角矩阵L和一个上三角矩阵U。

以上演示了如何使用Apache Commons Math来创建向量、矩阵以及执行基本线性代数运算和线性方程组求解。这些操作是在处理数值问题中不可或缺的工具,对于希望在IT行业深入应用数学计算的开发者而言,是一个很好的起点。

5. 数值方法算法

5.1 数值积分和微分

5.1.1 数值积分的理论基础

数值积分是解决无法找到精确解析解的积分问题的一种方法。在数值分析中,我们经常遇到需要计算定积分的场景,尤其是在处理复杂的数学模型时。数值积分的理论基础主要来源于牛顿-莱布尼茨公式的一个近似实现。

牛顿-莱布尼茨公式将定积分表达为被积函数在积分区间两端点的函数值之差,即: [ \int_{a}^{b} f(x) dx = F(b) - F(a) ] 其中,( F(x) ) 是 ( f(x) ) 的一个原函数。数值积分通过选取区间内若干个点的函数值,然后进行加权平均来近似这个差值。

在实际应用中,常用的数值积分方法包括梯形法则、辛普森法则和高斯求积等。每种方法都有其适用范围和误差控制策略。

5.1.2 数值微分的应用实例

数值微分是通过函数的离散值来近似求解函数导数的过程。对于给定函数 ( f(x) ),其在点 ( x ) 处的导数 ( f'(x) ) 可以用如下公式近似: [ f'(x) \approx \frac{f(x+h) - f(x)}{h} ] 这里,( h ) 是一个小的步长值。当 ( h ) 趋近于零时,近似值将趋近于真实的导数值。

数值微分在科学计算中非常有用,尤其是在实验数据处理和动态系统仿真中。例如,在工程领域,通过数值微分可以估算物体的瞬时速度和加速度。

下面是一个使用 Apache Commons Math 库中的数值微分功能的代码示例:

// 导入 Apache Commons Math 库中的数值微分包
***mons.math3.analysis.differentiation.DerivativeStructure;
***mons.math3.analysis.differentiation.UnivariateFunction;

public class NumericalDifferentiation {
    public static void main(String[] args) {
        UnivariateFunction f = x -> Math.sin(x);
        DerivativeStructure ds = new DerivativeStructure(1, 1, 0, Math.PI / 4);
        double result = f.value(ds.getValue());

        // 输出函数值和一阶导数近似值
        System.out.println("f(π/4) = " + result);
        System.out.println("f'(π/4) ≈ " + ds.getDerivative());
    }
}

在此代码段中,我们使用了 Apache Commons Math 库中的 DerivativeStructure 类来计算函数 ( f(x) = \sin(x) ) 在 ( x = \frac{\pi}{4} ) 处的一阶导数近似值。

5.2 方程求解器

5.2.1 一元与多元方程求解

一元与多元方程求解是数学和工程学中常见的问题。在很多情况下,这些方程没有封闭形式的解,或解的表达式过于复杂,因此需要借助数值方法进行求解。

Apache Commons Math 库提供了 UnivariateRealSolver MultivariateRealSolver 接口,分别用于求解一元和多元非线性方程。这些接口通过迭代方法,如二分法、牛顿法等,找到方程的根。

5.2.2 方程求解器的性能比较

为了确定最合适的求解器,开发者必须根据具体问题选择适当的方程求解策略。性能比较通常涉及收敛速度、计算精度和数值稳定性。不同的求解器有不同的优势和局限。

例如,牛顿法在函数可导且导数不为零的情况下收敛速度很快,但其需要一个好的初始猜测值,否则可能不收敛。而二分法在确定的区间内寻找根,不需计算导数,但速度相对较慢。

下面的代码展示了如何使用 Apache Commons Math 库中的 UnivariateRealSolver 求解一元方程:

``` mons.math3.analysis.solvers.BisectionSolver; mons.math3.analysis.solvers.UnivariateRealFunction; mons.math3.analysis.solvers.BaseSecantSolver.Method;

public class EquationSolvers { public static void main(String[] args) { UnivariateRealFunction func = x -> Math.pow(x, 3) - x - 1; BisectionSolver solver = new BisectionSolver(); solver.setAbsoluteAccuracy(1e-6); // 设置求解精度

    double root = solver.solve(100, func, -1, 2); // 在区间[-1, 2]内求解
    System.out.println("Root: " + root);
}

}


在此代码段中,我们使用 `BisectionSolver` 类求解方程 \( x^3 - x - 1 = 0 \) 在区间 \([-1, 2]\) 内的根。我们设置了解的绝对精度为 \(10^{-6}\),以确保解的准确度。

# 6. 统计分析工具

统计分析是数据分析的核心部分,它帮助我们理解数据集的特性,并通过数据来解释现象或者预测未来。在Apache Commons Math库中,统计分析工具提供了一系列功能强大的工具来执行描述性统计分析和高级统计测试。

## 6.1 描述性统计分析

描述性统计分析是统计分析中的基础,主要目标是用几个数字来概括整个数据集的特征。在这一部分,我们将介绍如何使用Apache Commons Math库计算常用的统计量和生成统计图表。

### 6.1.1 常用统计量的计算

在Apache Commons Math中,我们可以利用`DescriptiveStatistics`类来计算一组数据的中心趋势(如平均值、中位数)、分散程度(如方差、标准差)和其他统计量(如偏度、峰度)。

以下是使用`DescriptiveStatistics`类计算一组数据统计量的代码示例:

```***
***mons.math3.stat.descriptive.DescriptiveStatistics;

public class StatisticsExample {
    public static void main(String[] args) {
        // 创建数据集
        double[] data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};

        // 创建DescriptiveStatistics实例
        DescriptiveStatistics stats = new DescriptiveStatistics();

        // 添加数据到统计对象中
        for (double value : data) {
            stats.addValue(value);
        }

        // 计算并打印统计量
        System.out.println("Mean: " + stats.getMean());
        System.out.println("Median: " + stats.getPercentile(50));
        System.out.println("Standard Deviation: " + stats.getStandardDeviation());
        // 其他统计量的计算类似
    }
}

6.1.2 统计图表的生成与解读

虽然Apache Commons Math库主要集中在数学计算而不是可视化,但了解如何生成统计图表是数据分析过程的重要部分。图表能够直观地展示数据分布、趋势和异常点。

你可以使用如JFreeChart这样的第三方库来生成数据的图表。以下是一个简单的示例,展示了如何使用JFreeChart生成一个直方图:

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.statistics.HistogramDataset;
import org.jfree.data.statistics.HistogramType;

import javax.swing.*;
import java.awt.*;

public class ChartExample {
    public static void main(String[] args) {
        // 创建数据集
        double[] data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};
        // 创建HistogramDataset实例
        HistogramDataset dataset = new HistogramDataset();
        dataset.addSeries("Data", data, 5); // 第三个参数为桶数(bin count)

        // 创建直方图
        JFreeChart chart = ChartFactory.createHistogram(
                "Histogram Example", // 图表标题
                "Value", // X轴标签
                "Frequency", // Y轴标签
                dataset,
                HistogramType.RELATIVE_FREQUENCY,
                true, // 是否显示表格
                false // 是否是工具提示
        );

        // 创建图表面板并设置窗口
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(560, 370));
        JFrame frame = new JFrame("Histogram Example");
        frame.setContentPane(chartPanel);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

这个示例中,我们首先创建了一个 HistogramDataset 实例并添加了数据,然后使用 ChartFactory.createHistogram 方法来创建一个直方图,最后将图表嵌入到JFrame窗口中显示出来。

6.2 假设检验与回归分析

假设检验和回归分析是统计分析中的高级方法,它们帮助我们在数据上建立数学模型,从而进行预测或者推断数据之间的关系。

6.2.1 常用的假设检验方法

假设检验是用于统计推断的一种方法,其基本思想是基于样本数据来推断总体参数的可能范围。Apache Commons Math库提供了多种假设检验方法的实现,包括T检验、卡方检验等。使用这些方法时,你需要指定零假设(null hypothesis)和备择假设(alternative hypothesis),然后计算一个检验统计量及其P值来决定是否拒绝零假设。

这里我们以一个简单的T检验为例,说明如何使用Apache Commons Math库进行假设检验:

``` mons.math3.distribution.TDistribution; ***mons.math3.stat.inference.TTest;

public class HypothesisTestingExample { public static void main(String[] args) { // 样本数据 double[] sample1 = {1.2, 1.4, 1.6, 1.8, 2.0}; double[] sample2 = {1.7, 1.8, 1.9, 2.0, 2.1};

    // 使用T检验
    TTest test = new TTest();
    boolean significant = test.tTest(sample1, sample2, 0.05);

    // 输出检验结果
    if (significant) {
        System.out.println("Reject the null hypothesis.");
    } else {
        System.out.println("Fail to reject the null hypothesis.");
    }
}

}


在上述代码中,我们创建了两个样本数组`sample1`和`sample2`,使用T检验方法来检验两个样本均值是否存在显著差异(这里使用的是双侧检验,α=0.05),最后根据计算出的P值来决定是否拒绝零假设。

### 6.2.2 回归模型的建立与分析

回归分析是确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。Apache Commons Math库提供了线性回归的实现,通过`SimpleRegression`类,你可以创建简单的线性回归模型,并进行参数估计和预测。

下面是一个简单的线性回归模型建立的示例代码:

```***
***mons.math3.stat.regression.SimpleRegression;

public class RegressionAnalysisExample {
    public static void main(String[] args) {
        // 解释变量和响应变量
        double[] independent = {1.0, 2.0, 3.0, 4.0, 5.0};
        double[] dependent = {2.0, 3.5, 5.0, 6.0, 7.5};

        // 创建并训练SimpleRegression模型
        SimpleRegression model = new SimpleRegression(true);
        for (int i = 0; i < independent.length; i++) {
            model.addData(independent[i], dependent[i]);
        }

        // 获取回归统计量
        double slope = model.getSlope();
        double intercept = model.getIntercept();
        double r = model.getRSquare();

        // 输出回归结果
        System.out.println("Slope: " + slope);
        System.out.println("Intercept: " + intercept);
        System.out.println("Coefficient of Determination (R^2): " + r);
    }
}

在这段代码中,我们首先定义了两组变量 independent dependent ,分别代表解释变量和响应变量。我们创建了一个 SimpleRegression 实例并用数据来训练模型,最终输出了回归线的斜率、截距以及判定系数R²,这些参数可以帮助我们了解模型的拟合度和预测能力。

在实际应用中,你可能需要根据数据的分布和问题的性质来选择合适的统计分析工具,并对其进行适当的调整和优化。通过上述示例,你可以看到Apache Commons Math库为进行统计分析提供了非常便利的支持。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:Apache Commons Math是一个Java科学计算库,提供丰富的数学和统计功能,支持复杂数学运算。版本3.6包含多种数学组件,如基本数学操作、随机数生成、线性代数处理、数值方法、统计分析、特殊函数、优化算法、序列处理及组合数学。它在科学计算、数据分析、机器学习等多个领域得到广泛应用,简化了开发过程,提升了代码质量和效率。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值