تنظيف البيانات ثنائية الأبعاد والتحقّق منها
نظّف البيانات الصحيحة ثنائية الأبعاد وتحقّق منها: عالج الصفوف null، وتحقّق من حدود الفهارس، وقيّد القيم الخارجة عن النطاق، ووحّد أشكال المصفوفات متباينة الأطوال، وأنشئ تقارير تحقّق.
تنظيف البيانات ثنائية الأبعاد والتحقّق منها درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 6 من أصل 6. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 6 دروس في المجموع.
لماذا ننظّف المصفوفات ثنائية الأبعاد؟
الهدف: جعل بيانات الأعداد الصحيحة ثنائية الأبعاد آمنة ومتسقة. سنقوم بما يلي: (1) التعامل بأمان مع الصفوف null، (2) التحقق من الحدود لكل صف، (3) حصر القيم ضمن نطاق صالح، (4) توحيد الأشكال متفاوتة الأطوال عند الحاجة، و(5) إنشاء تقرير للتحقق.
القيم الفارغة والحدود
الخطوة 1: استبدلوا الصفوف null بمصفوفات فارغة، وانسخوا القيم بطريقة دفاعية. وفّروا أداة inBounds المساعدة للتحقق من أطوال الصفوف فرديًا.
public class Main {
// Make a defensive copy of m. Replace null rows with empty arrays.
static int[][] copyOrEmpty(int[][] m) {
if (m == null) return new int[0][0];
int[][] out = new int[m.length][];
for (int r = 0; r < m.length; r = r + 1) {
if (m[r] == null) {
out[r] = new int[0];
} else {
out[r] = new int[m[r].length];
for (int c = 0; c < m[r].length; c = c + 1) out[r][c] = m[r][c];
}
}
return out;
}
// Safe bounds check for jagged matrices
static boolean inBounds(int[][] m, int r, int c) {
return m != null && r >= 0 && r < m.length && m[r] != null && c >= 0 && c < m[r].length;
}
public static void main(String[] args) {
int[][] raw = new int[][] { null, {1, 2, 3}, {4} };
int[][] cleaned = copyOrEmpty(raw);
System.out.println("rows = " + cleaned.length);
for (int r = 0; r < cleaned.length; r = r + 1) System.out.println("row " + r + " len = " + cleaned[r].length);
System.out.println("inBounds(1,2) = " + inBounds(cleaned, 1, 2)); // true
System.out.println("inBounds(2,2) = " + inBounds(cleaned, 2, 2)); // false
}
}
حصر القيم
الخطوة 2: احصروا القيم ضمن نطاق صالح، مثل 0–100. تتحول القيم السالبة غير الصالحة إلى 0، وتتحول القيم الأكبر من الحد إلى 100.
public class Main {
static int clamp(int v, int lo, int hi) { if (v < lo) return lo; if (v > hi) return hi; return v; }
static void clampAll(int[][] m, int lo, int hi) {
if (m == null) return;
for (int r = 0; r < m.length; r = r + 1) {
if (m[r] == null) continue;
for (int c = 0; c < m[r].length; c = c + 1) m[r][c] = clamp(m[r][c], lo, hi);
}
}
static void print(int[][] m) {
for (int r = 0; r < m.length; r = r + 1) {
if (m[r] == null) { System.out.println("<null row>"); continue; }
for (int c = 0; c < m[r].length; c = c + 1) System.out.print(m[r][c] + (c + 1 < m[r].length ? " " : ""));
System.out.println();
}
}
public static void main(String[] args) {
int[][] m = { { -5, 101, 50 }, null, { 200 } };
System.out.println("before clamp:");
print(m);
clampAll(m, 0, 100);
System.out.println("after clamp [0..100]:");
print(m);
}
}
توحيد الشكل
الخطوة 3: وحّدوا الشكل ليصبح مستطيلًا، وذلك بملء كل صف قصير أو null حتى يصل إلى طول أطول صف، باستخدام قيمة pad مثل 0.
public class Main {
static int[][] padToMaxCols(int[][] m, int pad) {
if (m == null) return new int[0][0];
int rows = m.length;
int maxCols = 0;
for (int r = 0; r < rows; r = r + 1) if (m[r] != null && m[r].length > maxCols) maxCols = m[r].length;
int[][] out = new int[rows][maxCols];
for (int r = 0; r < rows; r = r + 1) {
int cols = (m[r] == null) ? 0 : m[r].length;
for (int c = 0; c < cols; c = c + 1) out[r][c] = m[r][c];
for (int c = cols; c < maxCols; c = c + 1) out[r][c] = pad; // pad missing cells
}
return out;
}
static void print(int[][] x) {
for (int r = 0; r < x.length; r = r + 1) {
for (int c = 0; c < x[r].length; c = c + 1) System.out.print(x[r][c] + (c + 1 < x[r].length ? " " : ""));
System.out.println();
}
}
public static void main(String[] args) {
int[][] jag = { {1, 23, 456}, {7, 8}, null, {90} };
int[][] rect = padToMaxCols(jag, 0);
print(rect);
}
}
تقرير التحقق
الخطوة 4: أنشئوا تقرير تحقق يحصي القيم السالبة، والقيم الأكبر من الحد، والصفوف null، وإجمالي الخلايا التي تمت زيارتها.
public class Main {
static class Report { int negatives; int overMax; int nullRows; int cells; }
static Report validate(int[][] m, int hi) {
Report r = new Report();
if (m == null) return r;
for (int i = 0; i < m.length; i = i + 1) {
if (m[i] == null) { r.nullRows = r.nullRows + 1; continue; }
for (int j = 0; j < m[i].length; j = j + 1) {
int v = m[i][j];
r.cells = r.cells + 1;
if (v < 0) r.negatives = r.negatives + 1;
if (v > hi) r.overMax = r.overMax + 1;
}
}
return r;
}
public static void main(String[] args) {
int[][] m = { { -5, 101, 50 }, null, { 200 } };
Report r = validate(m, 100);
System.out.println("cells=" + r.cells + ", negatives=" + r.negatives + ", overMax=" + r.overMax + ", nullRows=" + r.nullRows);
}
}
الطباعة مع تخطي الصفوف الفارغة
الخطوة 5: وفّروا طباعة بمحاذاة متناسقة تتخطى الصفوف null بأمان وتحترم طول كل صف.
public class Main {
static boolean inBounds(int[][] m, int r, int c) {
return m != null && r >= 0 && r < m.length && m[r] != null && c >= 0 && c < m[r].length;
}
static int[] widths(int[][] m) {
int maxCols = 0; if (m == null) return new int[0];
for (int r = 0; r < m.length; r = r + 1) if (m[r] != null && m[r].length > maxCols) maxCols = m[r].length;
int[] w = new int[maxCols];
for (int r = 0; r < m.length; r = r + 1) {
if (m[r] == null) continue;
for (int c = 0; c < m[r].length; c = c + 1) {
int len = Integer.toString(m[r][c]).length();
if (len > w[c]) w[c] = len;
}
}
for (int c = 0; c < w.length; c = c + 1) if (w[c] < 1) w[c] = 1;
return w;
}
static void printAlignedSkipNull(int[][] m) {
int[] w = widths(m);
for (int r = 0; r < m.length; r = r + 1) {
if (m[r] == null) { System.out.println("<skipped null row>"); continue; }
String line = "";
for (int c = 0; c < m[r].length; c = c + 1) {
String s = Integer.toString(m[r][c]);
while (s.length() < w[c]) s = " " + s;
line = line + s + (c + 1 < m[r].length ? " " : "");
}
System.out.println(line);
}
}
public static void main(String[] args) {
int[][] m = { { 1, 200, -3 }, null, { 45 } };
printAlignedSkipNull(m);
}
}
التحقق من الوصول الآمن
تحقق سريع: كيف تصلون بأمان إلى m[r][c] عند التعامل مع بيانات قد تكون متفاوتة الأطوال؟
مراجعة والخطوة التالية
مراجعة: نسختم البيانات بطريقة دفاعية، وتحكمتم في الفهارس، وحصرتم القيم، ووحّدتم الأشكال متفاوتة الأطوال، وأنشأتم ملخصات للتحقق. تجعل هذه اللبنات الخوارزميات اللاحقة على المصفوفات ثنائية الأبعاد أكثر متانة.
الأسئلة الشائعة
هل درس «تنظيف البيانات ثنائية الأبعاد والتحقّق منها» مجاني؟
نعم — نص درس «تنظيف البيانات ثنائية الأبعاد والتحقّق منها» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 6 دروس في المجموع.
ماذا ستتعلم في «تنظيف البيانات ثنائية الأبعاد والتحقّق منها»؟
نظّف البيانات الصحيحة ثنائية الأبعاد وتحقّق منها: عالج الصفوف null، وتحقّق من حدود الفهارس، وقيّد القيم الخارجة عن النطاق، ووحّد أشكال المصفوفات متباينة الأطوال، وأنشئ تقارير تحقّق. تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 6 من أصل 6.
كم من الوقت يستغرق درس «تنظيف البيانات ثنائية الأبعاد والتحقّق منها»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أساسيات المصفوفات ثنائية الأبعاد والتكرار المتداخل
- المصفوفات متباينة الأطوال وتنسيق الجداول
- القيم الكبرى للصفوف والأعمدة، والتحويل، والتنسيق
- مشروع مصغّر ثنائي الأبعاد: سجل الدرجات
- أدوات ثنائية الأبعاد كفئة مساعدة (إعادة الهيكلة)
- تنظيف البيانات ثنائية الأبعاد والتحقّق منها