Stack Overflow на русском Asked by MusaevElchin on November 15, 2021
Условие задачи:
Напишите метод
printOddNumbers
, который принимает массив и выводит в
консоль только нечётные числа из него через запятую. Конец вывода
должен перевести курсор на новую строку.Пример ввода:
[3,5,20,8,7,3,100]
Пример вывода:
3, 5, 7, 3
public class Main {
public static void main(String[] args) {
int[] arr = {2, 5, 5, 5, 8, 4, 5, 6, 8, 5};
printOddNumbers(arr);
}
public static void printOddNumbers(int[] arr) {
for (int x = 0; x < arr.length; x++)
if (arr[x] % 2 != 0)
System.out.print(arr[x] + ", ");
}
}
Вывод такой: 5, 5, 5, 5, 5,
Я не могу понять, как оформить решение так, чтобы последняя запятая не выводилась, наверное, я уже устал и не вижу очевидного решения. Буду благодарен, если кто-то также подскажет решение покороче.
Иногда мудрить не надо: https://ideone.com/AfmyyZ
import java.util.*;
class Ideone {
public static void main(String[] args) {
printOddNumbers(new int[] {3, 5, 20, 8, 7, 3, 100});
}
public static void printOddNumbers(int[] arr) {
var res = new ArrayList<String>();
for (int x : arr) {
if (x % 2 != 0) {
res.add(Integer.toString(x));
}
}
System.out.print(String.join(", ", res));
}
}
Answered by Qwertiy on November 15, 2021
Запятую надо ставить не после, а до элемента:
int[] arr = {2, 5, 5, 5, 8, 4, 5, 6, 8, 5};
String separator = ""; // перед первым элементом ничего не надо
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 != 0) {
System.out.print(separator); // сначала разделитель
System.out.print(arr[i]); // потом элемент
// if (separator.isEmpty())
separator = ", "; // разделитель перед всеми последующими
}
}
System.out.println();
Answered by Sergey on November 15, 2021
Вариант через итерацию
public class Main {
public static void main(String[] args) {
int[] arr = {2, 1, 4, 3, 2, 2, 2};
printOddNumbers(arr);
}
public static void printOddNumbers(int[] arr) {
boolean flag == true;
for (int x = 0; x < arr.length; x++) {
if(arr[x]%2 != 0){
if(flag){
System.out.print(arr[x]);
flag = false;
}else{
System.out.print(", " + arr[x]);
}
}
}
System.out.println();
}
}
Answered by Inwar2006 on November 15, 2021
Enterprise version
public class MyClass {
public static void main(String args[]) {
int[] array = new int[]{5,2,4,7,6,6,9};
printOdds(array);
}
private static void printOdds(int[] array) {
SignificantNumber[] temporalyArray = convertToSignificantNumberArray(array);
populateWithPrefixSelector(temporalyArray);
StringBuffer preparedString = prepareString(temporalyArray);
System.out.print(preparedString.toString());
}
private static void populateWithPrefixSelector(SignificantNumber[] temporalyArray) {
boolean firstMarked = false;
for(int i=0; i<temporalyArray.length; i++){
if(temporalyArray[i].isSuitable() && !firstMarked){
temporalyArray[i].setPrefixSelector(Order.FIRST);
firstMarked = true;
} else {
temporalyArray[i].setPrefixSelector(Order.OTHER);
}
}
}
private static SignificantNumber[] convertToSignificantNumberArray(int[] array){
SignificantNumber[] temporalyArray = new SignificantNumber[array.length];
for(int i=0; i<array.length; i++) {
temporalyArray[i] = new SignificantNumber(array[i]);
}
return temporalyArray;
}
private static StringBuffer prepareString(SignificantNumber[] temporalyArray) {
StringBuffer stringBuffer = new StringBuffer();
for(int i=0; i<temporalyArray.length; i++) {
stringBuffer.append(temporalyArray[i].getPrefixForValue());
stringBuffer.append(temporalyArray[i].getValueAsString());
}
return stringBuffer;
}
}
class SignificantNumber
implements SuitableValueForPrintInterface,
ValueWithPrintablePrefix<Order>,
PrintableValue {
int number;
Order order;
SignificantNumber(int number){
this.number = number;
}
public void setPrefixSelector(Order order){
this.order = order;
}
public boolean isSuitable() {
return andWrapper(number) == 1;
}
public String getPrefixForValue() {
if(isSuitable() && !isFirst()) {
return ", ";
}
return "";
}
public String getValueAsString() {
if(isSuitable()){
return Integer.toString(number);
} else {
return "";
}
}
private int andWrapper(int number) {
return number & 1;
}
private boolean isFirst() {
return this.order == Order.FIRST;
}
}
enum Order{
FIRST, OTHER;
}
interface SuitableValueForPrintInterface {
public boolean isSuitable();
}
interface ValueWithPrintablePrefix<T> {
public void setPrefixSelector(T prefixSelector);
public String getPrefixForValue();
}
interface PrintableValue {
public String getValueAsString();
}
Answered by rjhdby on November 15, 2021
Очевидно, что лучшим вариантом является вариант с поиском первого нечётного числа (8),
ну либо вариант с Regex
(10), если вы извращенец.
(1) Вариант со стримом-фильтровальщиком.
public static void printOddNumbers(int[] arr) {
arr = IntStream.of(arr).filter(i -> (i & 1) == 1).toArray();
StringBuilder sb = new StringBuilder();
if(arr.length != 0)
sb.append(arr[0]);
for (int i = 1; i < arr.length; i++)
sb.append(", ").append(arr[i]);
System.out.println(sb);
}
(2) Вариант только со стримом.
public static void printOddNumbers(int[] arr) {
System.out.println(IntStream.of(arr)
.filter(i -> (i & 1) == 1)
.mapToObj(Integer::toString)
.collect(Collectors.joining(", ")));
}
Варианты со списком.
(3) Объединение элементов вручную.
public static void printOddNumbers(int[] arr) {
ArrayList<Integer> list = new ArrayList<>();
for (int i : arr)
if((i & 1) == 1)
list.add(i);
StringBuilder sb = new StringBuilder();
// такой способ соединения с разделителем используется в методе Arrays.toString()
int limit = list.size() - 1;
if(limit != -1)
for (int i = 0;; i++) {
sb.append(list.get(i));
if(i == limit)
break;
sb.append(", ");
}
System.out.println(sb);
}
(4) Объединение с помощью метода String.join(CharSequence, Iterable<? extends CharSequence>)
. (видоизменённая реализация Qwertiy)
public static void printOddNumbers(int[] arr) {
ArrayList<String> list = new ArrayList<>();
for (int i : arr)
if ((i & 1) == 1)
list.add(i + "");
System.out.print(String.join(", ", list));
}
(5) Вариант с обрезанием возвращаемого значения метода List.toString()
.
public static void printOddNumbers(int[] arr) {
ArrayList<Integer> list = new ArrayList<>();
for (int i : arr)
if((i & 1) == 1)
list.add(i);
String toPrint = list.toString();
System.out.println(toPrint.substring(1, toPrint.length() - 1));
}
(6) Вариант со StringJoiner
.
public static void printOddNumbers(int[] arr) {
StringJoiner joiner = new StringJoiner(", ");
for (int i : arr)
if ((i & 1) == 1)
joiner.add(i + "");
System.out.println(joiner.toString());
}
(7) Вариант с boolean
переменной.
public static void printOddNumbers(int[] arr) {
boolean firstAdded = false;
StringBuilder sb = new StringBuilder();
for (int i : arr)
if((i & 1) == 1) {
if(firstAdded)
sb.append(", ");
else
firstAdded = true;
sb.append(i);
}
System.out.println(sb);
}
(8) Вариант с поиском первого нечётного числа. (Самый быстрый)
public static void printOddNumbers(int[] arr) {
StringBuilder sb = new StringBuilder();
int i = 0;
for (; i < arr.length; i++)
if((arr[i] & 1) == 1) {
sb.append(arr[i++]);
break;
}
for (; i < arr.length; i++)
if((arr[i] & 1) == 1)
sb.append(", ").append(arr[i]);
System.out.println(sb);
}
(9) Вариант с поиском последнего нечётного числа.
public static void printOddNumbers(int[] arr) {
int limit = -1;
for (int i = arr.length - 1; limit == -1; i--)
if((arr[i] & 1) == 1)
limit = i;
StringBuilder sb = new StringBuilder();
for (int i = 0;; i++)
if((arr[i] & 1) == 1) {
sb.append(arr[i]);
if(i < limit)
sb.append(", ");
else
break;
}
System.out.println(sb);
}
(10) Вариант с
Regex
.
public static void printOddNumbers(int[] arr) {
System.out.println(Arrays.toString(arr).replaceAll(", \d*[02468](?!\d)|\d*[02468](?:, |])|[\[\]]",""));
}
Варианты с обрезанием запятой.
(11) Первой.
public static void printOddNumbers(int[] arr) {
StringBuilder sb = new StringBuilder();
for (int i : arr)
if((i & 1) == 1)
sb.append(", ").append(i);
System.out.println(sb.isEmpty() ? sb : sb.substring(2));
}
(12) Последней. (Идея rjhdby)
public static void printOddNumbers(int[] arr) {
StringBuilder sb = new StringBuilder();
for (int i : arr)
if((i & 1) == 1)
sb.append(i).append(", ");
if (!sb.isEmpty())
sb.setLength(sb.length() - 2);
System.out.println(sb);
}
(13) Вариант с сепаратором. (Идея aleksandr barakin)
public static void printOddNumbers(int[] arr) {
StringBuilder sb = new StringBuilder();
String separator = "";
for (int i : arr)
if ((i & 1) == 1) {
sb.append(separator).append(i);
if (separator.isEmpty())
separator = ", ";
}
System.out.println(sb);
}
(14) Вариант с компиляцией строки при помощи методов анонимного класса.
public static void printOddNumbers(int[] arr) {
System.out.println(new Object() {
StringBuilder compile() {
StringBuilder sb = new StringBuilder();
int i = getNextIndex(0);
if(i != -1) while(true) {
sb.append(arr[i]);
i = getNextIndex(i + 1);
if(i == -1)
break;
sb.append(", ");
}
return sb;
}
int getNextIndex(int index) {
for (int i = index; i < arr.length; i++)
if((arr[i] & 1) == 1)
return i;
return -1;
}
}.compile());
}
(15) Варианты с рекурсией и обрезанием массива с начала.
(На самом деле есть ещё два варианта с обрезанием массива с конца, но они настолько похожи на эти, что я решил их не включать)
С помощью индекса.
public static void printOddNumbers(int[] arr) {
System.out.println(new Object() {
StringBuilder recursion(int[] array, int startIndex) {
if (array.length == startIndex)
return new StringBuilder();
if ((array[startIndex] & 1) == 1) {
StringBuilder result = new StringBuilder().append(array[startIndex]);
StringBuilder sb = recursion(array, startIndex + 1);
if (sb.length() != 0)
result.append(", ").append(sb);
return result;
} else
return recursion(array, startIndex + 1);
}
}.recursion(arr, 0));
}
С помощью копирования массивов.
public static void printOddNumbers(int[] arr) {
System.out.println(new Object() {
int[] cropFirstElement(int[] array) {
int[] result = new int[array.length-1];
System.arraycopy(array, 1, result, 0, result.length);
return result;
}
StringBuilder recursion(int[] array) {
if (array.length == 0)
return new StringBuilder();
if ((array[0] & 1) == 1) {
StringBuilder result = new StringBuilder().append(array[0]);
StringBuilder sb = recursion(cropFirstElement(array));
if (sb.length() != 0)
result.append(", ").append(sb);
return result;
} else
return recursion(cropFirstElement(array));
}
}.recursion(arr));
}
(16) Варианты с рекурсией и ополовиниванием массива.
С помощью индексов.
public static void printOddNumbers(int[] arr) {
System.out.println(arr.length == 0 ? "" : new Object() {
StringBuilder recursion(int[] array, int startIndex, int endIndex) {
if (endIndex - startIndex == 1)
if ((array[startIndex] & 1) == 1)
return new StringBuilder(array[startIndex] + "");
else
return new StringBuilder();
StringBuilder sb1 = recursion(array, startIndex, startIndex + (endIndex - startIndex) / 2),
sb2 = recursion(array, startIndex + (endIndex - startIndex) / 2, endIndex);
if (sb2.isEmpty())
return sb1;
else
return sb1.append(", ").append(sb2);
}
}.recursion(arr, 0, arr.length));
}
С помощью копирования массивов.
public static void printOddNumbers(int[] arr) {
System.out.println(arr.length == 0 ? "" : new Object() {
StringBuilder recursion(int[] array) {
if (array.length == 1)
if ((array[0] & 1) == 1)
return new StringBuilder(array[0] + "");
else
return new StringBuilder();
int halfOfLength = array.length / 2;
int[] arr1 = new int[halfOfLength],
arr2 = new int[array.length - halfOfLength];
System.arraycopy(array, 0, arr1, 0, arr1.length);
System.arraycopy(array, halfOfLength, arr2, 0, arr2.length);
StringBuilder sb1 = recursion(arr1),
sb2 = recursion(arr2);
if (sb2.isEmpty())
return sb1;
else
return sb1.append(", ").append(sb2);
}
}.recursion(arr));
}
(17) Вариант с созданием нового массива из нечётных чисел вручную.
public static void printOddNumbers(int[] arr) {
int lim = 0;
int[] oddArr = new int[arr.length];
for (int i : arr)
if((i & 1) == 1)
oddArr[lim++] = i;
StringBuilder sb = new StringBuilder();
if(--lim != -1)
for (int i = 0;; i++) {
sb.append(oddArr[i]);
if(i == lim)
break;
sb.append(", ");
}
System.out.println(sb);
}
(18) Вариант с проверкой длины (пустоты) StringBuilder(а)
.
public static void printOddNumbers(int[] arr) {
StringBuilder sb = new StringBuilder();
for (int i : arr)
if((i & 1) == 1)
sb.append(sb.isEmpty() ? "" : ", ").append(i);
System.out.println(sb);
}
(19) Вариант с двойным пробеганием массива и сохранением количества нечётных чисел.
public static void printOddNumbers(int[] arr) {
int count = 0;
for (int i : arr)
if ((i & 1) == 1)
count++;
StringBuilder sb = new StringBuilder();
for (int i : arr)
if ((i & 1) == 1) {
sb.append(i);
if (--count == 0)
break;
sb.append(", ");
}
System.out.println(sb);
}
(20) Вариант с пробеганием массива с двух сторон.
public static void printOddNumbers(int[] arr) {
StringBuilder sb1 = new StringBuilder(),
sb2 = new StringBuilder();
int index1 = 0, index2 = arr.length - 1;
while (index1 < index2) {
if ((arr[index1] & 1) == 1)
sb1.append(arr[index1]).append(", ");
index1++;
if ((arr[index2] & 1) == 1)
sb2.insert(0, ", " + arr[index2]);
index2--;
}
if (index1 == index2 && (arr[index1] & 1) == 1)
System.out.println(sb1.append(arr[index1]).append(sb2));
else if (sb2.length() > 0)
System.out.println(sb1.append(sb2.substring(2)));
else
System.out.println(sb1);
}
(21) Вариант с пробеганием массива в обе стороны из середины.
public static void printOddNumbers(int[] arr) {
StringBuilder sb1 = new StringBuilder(),
sb2 = new StringBuilder();
int index1 = arr.length / 2 - 1 /* '- 1' на случай, если массив пустой */,
index2 = index1 + 1;
while (index1 > -1) {
if ((arr[index1] & 1) == 1)
sb1.insert(0, arr[index1] + ", ");
index1--;
}
while (index2 < arr.length) {
if ((arr[index2] & 1) == 1)
sb2.append(", ").append(arr[index2]);
index2++;
}
if (sb2.isEmpty())
System.out.println(sb1);
else
System.out.println(sb1.append(sb2.substring(2)));
}
(22) Совсем ненормальный вариант с
regex
и двумя стримами один в другом.
public static void printOddNumbers(int[] arr) {
System.out.println(
Stream.of(
IntStream.of(arr)
.mapToObj(Integer::toString)
.collect(Collectors.joining(","))
.split("(?<=[13579]),(?=\d*[13579](?!\d))|(?:,|^)(?:\d*[02468](?:,|$))+")
).filter(s -> !s.isEmpty())
.collect(Collectors.joining(", "))
);
}
(23) Вариант с вырезанием всех чётных чисел.
public static void printOddNumbers(int[] arr) {
for (int i = 0; i < arr.length;)
if ((arr[i] & 1) == 0) {
int[] newArr = new int[arr.length-1];
System.arraycopy(arr, 0, newArr, 0, i);
System.arraycopy(arr, i + 1, newArr, i, newArr.length - i);
arr = newArr;
} else
i++;
StringBuilder sb = new StringBuilder();
if (arr.length > 0)
for (int i = 0;;) {
sb.append(arr[i]);
if (++i == arr.length)
break;
sb.append(", ");
}
System.out.println(sb);
}
(24) Вариант с переносом всех нечётных чисел в начало массива.
public static void printOddNumbers(int[] arr) {
int index = 0;
for (; index < arr.length; index++)
if ((arr[index] & 1) == 0)
break;
for (int i = index + 1; i < arr.length; i++)
if ((arr[i] & 1) == 1 && i != index) {
// arr[index++] = arr[i] - (arr[i] = 0);
arr[index] = arr[i];
arr[i] = 0; // любое чётное число
index++;
}
StringBuilder sb = new StringBuilder();
if (index != 0)
sb.append(arr[0]);
for (int i = 1; i < index; i++)
sb.append(", ").append(arr[i]);
System.out.println(sb);
}
(25) Вариант с конечным автоматом.
public static void printOddNumbers(int[] arr) {
class FSM {
final int NOT_FOUNT_FIRST_ODD_NUMBER_YET = 0;
final int AT_FIRST_ODD_NUMBER = 1;
final int AT_ODD_NUMBER = 2;
final int AT_EVEN_NUMBER = 3;
final int AT_THE_END_OF_THE_ARRAY = 4;
int currentState = NOT_FOUNT_FIRST_ODD_NUMBER_YET;
void NOT_FOUNT_FIRST_ODD_NUMBER_YET() {
if (incrementAndCheckIndex())
if ((arr[index] & 1) == 1)
currentState = AT_FIRST_ODD_NUMBER;
}
void AT_FIRST_ODD_NUMBER() {
result.append(arr[index]);
setEvenOrOddState();
}
void AT_ODD_NUMBER() {
result.append(", ").append(arr[index]);
setEvenOrOddState();
}
void AT_EVEN_NUMBER() {
setEvenOrOddState();
}
boolean incrementAndCheckIndex() {
if (++index == arr.length) {
currentState = AT_THE_END_OF_THE_ARRAY;
return false;
}
return true;
}
void setEvenOrOddState() {
if (incrementAndCheckIndex())
currentState = (arr[index] & 1) == 1 ? AT_ODD_NUMBER : AT_EVEN_NUMBER;
}
void update() {
if (currentState == NOT_FOUNT_FIRST_ODD_NUMBER_YET)
NOT_FOUNT_FIRST_ODD_NUMBER_YET();
else if (currentState == AT_FIRST_ODD_NUMBER)
AT_FIRST_ODD_NUMBER();
else if (currentState == AT_ODD_NUMBER)
AT_ODD_NUMBER();
else if (currentState == AT_EVEN_NUMBER)
AT_EVEN_NUMBER();
}
int index = -1;
StringBuilder result = new StringBuilder();
StringBuilder compile() {
while (currentState != AT_THE_END_OF_THE_ARRAY)
update();
return result;
}
}
System.out.println(new FSM().compile());
}
Answered by Имя Фамилия on November 15, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP