我有一个简单的数组,有点像这样
1 2 3 4 5 6 7 8 9
6 2 7 2 9 6 8 10 5
2 6 4 7 8 4 3 2 5
9 8 7 5 9 7 4 1 10
5 3 6 8 2 7 3 7 2
所以,我们称之为matrix[5][9]
。我希望现在删除此矩阵中包含特定值的每一行,在本例中为10,所以我留下了......
1 2 3 4 5 6 7 8 9
2 6 4 7 8 4 3 2 5
5 3 6 8 2 7 3 7 2
答案 0 :(得分:8)
这是一个你可以运行的示例类,我相信你正在寻找什么。从2D数组中删除行是很棘手的事情,因为像@KalebBrasee所说,你不能真正“删除”它们,而是你必须改造一个全新的2D数组。希望这有帮助!
import java.util.ArrayList;
import java.util.List;
public class Matrix
{
private double[][] data;
public Matrix(double[][] data)
{
int r= data.length;
int c= data[0].length;
this.data= new double[r][c];
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
this.data[i][j] = data[i][j];
}
}
}
/* convenience method for getting a
string representation of matrix */
public String toString()
{
StringBuilder sb = new StringBuilder(1024);
for(double[] row : this.data)
{
for(double val : row)
{
sb.append(val);
sb.append(" ");
}
sb.append("\n");
}
return(sb.toString());
}
public void removeRowsWithValue(final double value)
{
/* Use an array list to track of the rows we're going to want to
keep...arraylist makes it easy to grow dynamically so we don't
need to know up front how many rows we're keeping */
List<double[]> rowsToKeep = new ArrayList<double[]>(this.data.length);
for(double[] row : this.data)
{
/* If you download Apache Commons, it has built-in array search
methods so you don't have to write your own */
boolean found = false;
for(double testValue : row)
{
/* Using == to compares doubles is generally a bad idea
since they can be represented slightly off their actual
value in memory */
if(Double.compare(value,testValue) == 0)
{
found = true;
break;
}
}
/* if we didn't find our value in the current row,
that must mean its a row we keep */
if(!found)
{
rowsToKeep.add(row);
}
}
/* now that we know what rows we want to keep, make our
new 2D array with only those rows */
this.data = new double[rowsToKeep.size()][];
for(int i=0; i < rowsToKeep.size(); i++)
{
this.data[i] = rowsToKeep.get(i);
}
}
public static void main(String[] args)
{
double[][] test = { {1, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 3, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 10},
{5, 3, 6, 8, 2, 7, 3, 7, 2} };
//make the original array and print it out
Matrix m = new Matrix(test);
System.out.println(m);
//remove rows with the value "10" and then reprint the array
m.removeRowsWithValue(10);
System.out.println(m);
}
}
答案 1 :(得分:5)
使用System.arraycopy
或使用java.util.List
代替数组。 ArrayList
可以快速访问随机元素和慢remove
方法,它与LinkedList
相反。你必须自己选择。
答案 2 :(得分:1)
您无法从Java内置数组数据结构中删除元素。您将不得不创建一个长度比第一个数组少一个的新数组,并将所有数组复制到该数组中,除了您要删除的数组。
答案 3 :(得分:1)
在那里你必须重新创建阵列并丢弃旧阵列。无法更改现有数组的维度 - 如果需要此类数据结构,则应根据集合(ArrayList<ArrayList<Double>>
)构建矩阵,在那里可以轻松删除行。
回到数组 - 想法是收集你想要保留的所有行(double []数组),用这些行创建一个结果数组,并用Matrix上的new on替换旧数据:
public void doSomethingWith(Matrix in) {
List<double[]> survivingRows = new ArrayList<double[]>();
for (double[] row:in.getRows()) {
if (isAGoodOne(row)) {
survivingRows.add(row);
}
}
double[][] result = new double[survivingRows][];
for (int i = 0; i < result.length; i++) {
result[i] = survivingRows.get(i);
}
in.setArray(result);
}
答案 4 :(得分:0)
我的看法:
import java.util.Arrays;
public class RemoveArrayRow {
private static <T> T[] concat(T[] a, T[] b) {
final int alen = a.length;
final int blen = b.length;
if (alen == 0) {
return b;
}
if (blen == 0) {
return a;
}
final T[] result = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), alen + blen);
System.arraycopy(a, 0, result, 0, alen);
System.arraycopy(b, 0, result, alen, blen);
return result;
}
public static void main(String[] args) {
double[][] d = { {11, 2, 3, 4, 5, 6, 7, 8, 9, 0},
{12, 2, 3, 4, 5, 6, 7, 8, 9, 1},
{13, 2, 3, 4, 5, 6, 7, 8, 9, 2},
{14, 2, 3, 4, 5, 6, 7, 8, 9, 3},
{15, 2, 3, 4, 5, 6, 7, 8, 9, 4} };
//remove the fourth row:
// (1)
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
// (2)
double[][] d2 = new double[d.length - 1][d[0].length];
System.arraycopy(d, 0, d2, 0, 3);
System.arraycopy(d, 4, d2, 3, 1);
System.out.print(d1.length);
System.out.print(d2.length);
}
}
(1)
如果排除用于连接两个数组的concat()
函数,则在一行中完成:
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
另见this question。这就是concat()
函数的代码来自的地方。
(2)
此方法更快,仅使用已有的功能。
答案 5 :(得分:0)
我的java语法有点生疏,但以下内容如果被视为伪代码将起作用
public Matrix removeRows(Matrix input) {
int[][] output = new int[input.numRows][input.numColumns]();
int i = 0;
for (int[] row : input.rows()) { // Matrix.rows() is a method that returns an array of all the rows in the matrix
if (!row.contains(10)) {
output[i] = row;
}
}
return output
答案 6 :(得分:0)
由于无法避免创建新的2D数组来包含删除后的数据,因此首先创建一个与[] []具有相同维度的新2D int [] [] b。其次,循环通过[] [],将a分配给b并在包含特定值时向上移动b行。和健全性检查最后一行,它可以包含特定数据。
public static int[][] remove(int[][] a, int v) {
int r = a.length;
int c = a[0].length;
int[][] b = new int[r][c];
int red = 0;
boolean s = false;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
b[i - red][j] = a[i][j];
if (a[i][j] == v) {
red += 1;
if(i==r-1){
s = true;
}
break;
}
}
}
//check last row
if(s){
for(int i = r-red;i <r-red +1; i++ )
for (int j = 0; j<c; j++){
b[i][j] = 0;
}
}
return b;
}
public static void main(String[] args){
int[][] a = { {1, 2, 3, 4, 5, 6, 7, 8, 1},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 2, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 1},
{5, 3, 6, 8, 2, 7, 3, 1, 1} };
print(remove(a, 10));
}
public static void print(int[][] a) {
int r = a.length;
int c = a[0].length;
int red = 0;
for (int i = 0; i < r; i++) {
System.out.printf("\nrow %d, \n", i);
for (int j = 0; j < c; j++) {
System.out.printf("%d, ", a[i][j]);
}
}
}
答案 7 :(得分:0)
这可能不是一个确切的解决方案,而是一个如何使用System.arraycopy实现它的概念。
在下面的示例中,我想复制除第一行之外的所有行。在您的情况下,您可以跳过包含10的那些行。
String[][] src = getSheetData(service, spreadSheetId, range);
String[][] dest = new String[src.length-1][src[0].length];
for (int i = 1; i < src.length; i++) {
System.arraycopy(src[i], 0, dest[i-1], 0, src[0].length-1);
}
答案 8 :(得分:0)
您可以为此使用 IntStream.noneMatch
方法:
int[][] arr1 = {
{1, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 3, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 10},
{5, 3, 6, 8, 2, 7, 3, 7, 2}};
int[][] arr2 = Arrays.stream(arr1)
.filter(row -> Arrays.stream(row).noneMatch(i -> i == 10))
.toArray(int[][]::new);
// output
Arrays.stream(arr2).map(Arrays::toString).forEach(System.out::println);
输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 6, 4, 7, 8, 4, 3, 2, 5]
[5, 3, 6, 8, 2, 7, 3, 7, 2]