* Форматиране на низове – примерна задача
Публикувано на 26 януари 2017 в раздел ПИК3 Java.
В долната задача демонстрирам употребата на String.format(). Дадена е следната задача: по подадено число N, да се отпечата чрез стандартния изход матрица с размерност NxN със звезди по диагоналите и празни интервали за останалите елементи.
Обикновено хората започват да търсят решение чрез вложени цикли, например:
public class MatrixStarDiagonals { public static void main(String[] args) { int N = 10; for (int i = 0; i <= N; i++) { StringBuilder strb = new StringBuilder(N); if (i == N/2 + N%2) continue; for (int j = 0; j <= N; j++) { if (N%2==1 && i==N/2 && j==N/2) continue; else if (N%2==1 && i==N/2+1 && j==N/2+1) continue; else if (i==j || N-i==j) strb.append("*"); else if(j!=N/2+N%2) strb.append(" "); } System.out.println(strb.toString()); } } }
Това решение е далеч от оптимално - има вложен цикъл. Вероятно може да се оптимизира като се премахне този проблем, но при всички случаи има много проверки за различни ситуации - четно, нечетно и т.н. Освен това се налага употреба на StringBuilder, за да не се печата символ по символ на екрана.
Чрез форматирани низове същото може да се постигне елементарно, с много по-малко проверки и печатайки директно цели редове и без вложен цикъл:
public class MatrixStarDiagonals { public static void main(String[] args) { int N = 10; for (int i = 1; i <= N; i++) { String res = String.format("%" + ((i <= N / 2) ? i : N - i + 1) + "s", "*"); if (N - 2 * i + 1 != 0) res += String.format("%" + ((i <= N / 2) ? N - 2 * i + 1 : 2 * i - N - 1) + "s", "*"); System.out.format("%1$-"+ N + "s"+"%n", res); } } }
Естествено, изучаването на подобни неща не е нормална част за курс по ООП, но все пак е хубаво упражнение, което показва, че ученето на printf в началния курс по програмиране на C не остава безполезно при преминаване към програмиране от по-високо ниво.
П.П. Едноредово решение (в името на спорта):
public class MatrixStarDiagonals { public static void main(String[] args) { for (int N=10, i=1; i<=N; i++) System.out.format("%1$-"+ N + "s"+"%n",String.format("%"+((i<=N/2)?i:N-i+1)+"s"+((N-2*i+1!=0)?"%"+((i<=N/2)?N-2*i+1:2*i-N-1)+"s":""), "*", "*")); } }
При варианта с вложените цикли първите две else са излишни. Също така има много излишни проверки.
Последните два варианта не запълват матрицата с интервали в дясно от двата диагонали, което не удовлетворява условието на задачата!
Здравей,
По вторият коментар - добавих padding в примерите и вече поставя интервали вдясно. Забележката беше коректна, въпреки че визуално на екрана няма разлика.
По първият - споделете по-просто решение без излишните проверки :)
//Това решение е лесно за четене и бързо за изпълнение, обхожда всеки елемент на матрицата.
Изглежда елегантно и разбираемо.