Java 如何删除二维数组中的一行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1805147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to remove a row in two-dimensional array
提问by AlexT
I have a simple array, sort of like this
我有一个简单的数组,有点像这样
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
So, let's call this matrix[5][9]
. I wish to now remove every row within this matrix that contains a certain value, in this case 10, so I am left with...
所以,让我们称之为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
采纳答案by Brent Writes Code
Here's a sample class you can run that I believe does what you're looking for. Removing rows from 2D arrays is tricky business because like @KalebBrasee said, you can't really "remove" them, but rather you have to make a whole new 2D array instead. Hope this helps!
这是您可以运行的示例类,我相信它可以满足您的需求。从二维数组中删除行是一件棘手的事情,因为就像@KalebBrasee 所说的那样,你不能真正“删除”它们,而是必须创建一个全新的二维数组。希望这可以帮助!
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);
}
}
回答by Kaleb Brasee
You can't remove elements from the Java built-in array data structure. You'll have to create a new array that has a length one less than the first array, and copy all the arrays into that array EXCEPT the one you want to remove.
您不能从 Java 内置数组数据结构中删除元素。您必须创建一个长度比第一个数组小 1 的新数组,并将所有数组复制到该数组中,除了要删除的数组。
回答by Krzysiek Goj
Use System.arraycopy
oruse java.util.List
instead of arrays. ArrayList
has fast access to random elements and a slow remove
method, it's the opposite with LinkedList
. You have to choose for yourself.
使用或使用代替数组。具有对随机元素的快速访问和缓慢的方法,与. 你必须自己选择。System.arraycopy
java.util.List
ArrayList
remove
LinkedList
回答by Marius Burz
My take:
我的看法:
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)
If you exclude the concat()
function used for concatenating two arrays, it's done in one line:double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
See this questionas well. That's where the code for the concat()
function comes from.
(1)
如果排除concat()
用于连接两个数组的函数,则在一行中完成:也double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
请参阅此问题。这就是concat()
函数代码的来源。
(2)
This method is faster and only uses already available functions.
(2)
这种方法速度更快,并且只使用已经可用的功能。
回答by Andreas Dolk
At the and you have to recreate the array and discard the old one. Changing the dimension of an existing array is not possible - if want this type of datastructure, then you should build the matrix based on Collections (ArrayList<ArrayList<Double>>
), there you can remove a row easily.
在 and 你必须重新创建数组并丢弃旧的。更改现有数组的维度是不可能的 - 如果想要这种类型的数据结构,那么您应该基于 Collections ( ArrayList<ArrayList<Double>>
)构建矩阵,在那里您可以轻松删除一行。
Back to arrays - the idea is to collect all rows (double[] arrays) that you want to keep, create a result array with those rows and replace the old one with the new on on Matrix:
回到数组——我们的想法是收集你想要保留的所有行(double[] 数组),用这些行创建一个结果数组,并在 Matrix 上用新的替换旧的:
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);
}
回答by inspectorG4dget
My java syntax is a little rusty, but the following, if treated as pseudocode will work
我的 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
回答by Sola Yang
Since it cannot avoid creating new 2D array to contain the after-removed data, firstly, create a new 2D int[][] b with same dimension as a[][]. secondly, loop through a[][], assign a to b and move b row up when a contain specific value. and sanity check the last row, which can contain specific data.
由于无法避免创建新的二维数组来包含删除后的数据,因此首先创建一个与 a[][] 维度相同的新二维 int[][] b。其次,循环遍历 a[][],将 a 分配给 b 并在 a 包含特定值时将 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]);
}
}
}
回答by hemanto
This may not be an exact solution but a concept of how you can achieve it using System.arraycopy.
这可能不是一个精确的解决方案,而是一个关于如何使用 System.arraycopy 实现它的概念。
In the example below, I want to copy all the rows except the first row. In your case, you can skip those rows which contain 10.
在下面的示例中,我想复制除第一行之外的所有行。在您的情况下,您可以跳过那些包含 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);
}
参考:https: //docs.oracle.com/javase/6/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,% 20int%29