سؤال

لدي مجموعة بسيطة، نوع من هذا القبيل

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
هل كانت مفيدة؟

المحلول

وهنا فئة عينة يمكنك تشغيل أعتقد أنه يفعل ما كنت تبحث عنه. إزالة الصفوف من صفائف 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);
    }
}

نصائح أخرى

يستخدم System.arraycopy أو يستخدم java.util.List بدلا من المصفوفات. ArrayList لديه وصول سريع إلى العناصر العشوائية وبطيء remove الأسلوب، بل هو العكس مع LinkedList.عليك أن تختار لنفسك.

ولا يمكنك إزالة عناصر من جافا المدمج في بنية بيانات صفيف. سيكون لديك لإنشاء مجموعة جديدة يبلغ طولها أقل من واحد من مجموعة الأولى، ونسخ كافة صفائف إلى أن مجموعة باستثناء واحدة تريد إزالته.

وفي ولديك لإعادة مجموعة وتجاهل القديم. تغيير البعد من صفيف موجودة ليس من الممكن - لو تريد هذا النوع من بنية بيانات، ثم عليك أن بناء مصفوفة على أساس مجموعات (ArrayList<ArrayList<Double>>)، وهناك يمكنك إزالة صف بسهولة

عودة إلى المصفوفات - والفكرة هي لجمع جميع الصفوف (مزدوجة [] المصفوفات) التي تريد الاحتفاظ بها، إنشاء مجموعة النتيجة مع تلك الصفوف واستبدال القديم مع الجديد على على مصفوفة:

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);
}

وتركيب جافا بلدي قليلا صدئ، ولكن ما يلي، إذا تعامل على أنها شبة الكود سيعمل

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

وبلدي يأخذ:

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));
انظر هذا السؤال كذلك. وهنا يأتي رمز وظيفة concat() من.

و(2)
هذا الأسلوب هو أسرع ويستخدم فقط الوظائف المتاحة بالفعل.

ومنذ ذلك لا يمكن تجنب خلق مجموعة 2D جديدة لاحتواء البيانات بعد إزالتها، أولا، إنشاء الباحث 2D الجديد [] [] ب مع نفس البعد باعتباره [] []. ثانيا، من خلال حلقة [] []، تعيين لب والتحرك ب الصف لأعلى عندما يحتوي على قيمة معينة. والتعقل التحقق من الصف الأخير، والتي يمكن أن تحتوي على بيانات محددة.

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]);
        }
    }
}

وهذا قد لا يكون حلا المحدد ولكن مفهوم كيف يمكن تحقيق ذلك باستخدام 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);
}

والمرجعي: <لأ href = "https://docs.oracle.com/javase/6/docs/api/java/lang/System.html#arraycopy٪28java.lang.Object،٪20int،٪20java. lang.Object،٪ 20int،٪ 20int٪ 29 "يختلط =" نوفولو noreferrer "> https://docs.oracle.com/javase/6/docs/api/java/lang/System.html#arraycopy٪28java.lang .Object،٪ 20int،٪ 20java.lang.Object،٪ 20int،٪ 20int٪ 29

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top