Возьмите строку, состоящую из строчных и прописных букв, и отсортируйте ее таким образом, чтобы прописные и строчные буквы шли поочередно, но отсортировано.
Введите строку: HellLoWoRld.
Пример вывода:
Отсортированная строка: HdLeRlWloo.
Мое решение было
import java.util.Arrays;
import java.util.Scanner;
public class SortDriver {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the String: ");
String input = scanner.nextLine();
String sortedString = sortString(input);
System.out.println("The Sorted String is: " + sortedString);
}
public static String sortString(String str) {
StringBuilder sorted = new StringBuilder();
// Separate lowercase and uppercase letters
StringBuilder lower = new StringBuilder();
StringBuilder upper = new StringBuilder();
for (char ch : str.toCharArray()) {
if (Character.isLowerCase(ch)) {
lower.append(ch);
} else if (Character.isUpperCase(ch)) {
upper.append(ch);
}
}
// Sort the lowercase and uppercase letters
char[] lowerChars = lower.toString().toCharArray();
char[] upperChars = upper.toString().toCharArray();
Arrays.sort(lowerChars);
Arrays.sort(upperChars);
// Merge the sorted lowercase and uppercase letters alternately
int i = 0, j = 0;
while (i < lowerChars.length || j < upperChars.length) {
if (i < lowerChars.length) {
sorted.append(lowerChars[i++]);
}
if (j < upperChars.length) {
sorted.append(upperChars[j++]);
}
}
return sorted.toString();
}
}
Однако я не все правильно понимаю.
Proposed grade: 37.50 / 100
Result Description
Failed tests
Test 2: string sort testcase2
Test 3: string sort testcase1
Test 4: string sort testcase4
Test 5: string sort testcase5
Test 6: string sort testcase6
Test 1: string sort testcase3
Summary of tests
*Note: All the test cases might not have same weightage
+------------------------------+
| 8 tests run/ 3 tests passed |
+------------------------------+
Каким должен быть ответ для этой программы или мой подход совершенно неправильный?
Вам необходимо явно показать входные данные и ожидаемый результат. В вашем вопросе не указано, ожидается ли ваш результат или то, что вы получаете.
Комментарий @OneCricketeer был верным. Измените последний цикл while, чтобы сначала добавлять заглавные буквы.
while (i < lowerChars.length || j < upperChars.length) {
if (j < upperChars.length) {
sorted.append(upperChars[j++]);
}
if (i < lowerChars.length) {
sorted.append(lowerChars[i++]);
}
}
Поскольку вы работаете с буквами, если это не lower
регистр, то это должен быть upper
регистр, поэтому вам не нужен отдельный тест. Поэтому, когда вы делите строку на строки верхнего и нижнего регистра, просто выполните:
for (char ch : str.toCharArray()) {
if (Character.isLowerCase(ch)) {
lower.append(ch);
} else {
upper.append(ch);
}
}
Обратите внимание, что некоторые проверки случаев (например, для цифр) возвращают значение false в обоих случаях. Но это не должно применяться здесь, если вы не хотите исключить не-буквы, которые не были упомянуты в вашем вопросе.
В вашем решении есть две проблемы:
Мы можем добиться большего (используйте большой объем данных, чтобы увидеть разницу).
Оптимизированное решение:
public String sort(String input) {
char[] chars = input.toCharArray();
int n = chars.length;
int lowercaseIndex = 0;
int uppercaseIndex = n - 1;
while (lowercaseIndex <= uppercaseIndex) {
if (Character.isLowerCase(chars[lowercaseIndex])) {
lowercaseIndex++;
} else if (Character.isUpperCase(chars[uppercaseIndex])) {
uppercaseIndex--;
} else {
swap(chars, lowercaseIndex, uppercaseIndex);
lowercaseIndex++;
uppercaseIndex--;
}
}
// Sort the separated lowercase and uppercase letters in place
Arrays.sort(chars, 0, lowercaseIndex);
Arrays.sort(chars, lowercaseIndex, n);
// Merge sorted lowercase and uppercase letters alternately in place
StringBuilder sortedString = new StringBuilder();
for (int i = 0, j = lowercaseIndex; i < lowercaseIndex || j < n; i++, j++) {
if (i < lowercaseIndex) {
sortedString.append(chars[i]);
}
if (j < n) {
sortedString.append(chars[j]);
}
}
return sortedString.toString();
}
private static void swap(char[] chars, int i, int j) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
Ваш метод лишь немного более эффективен для символов огромных строк (100_000). Но это не имеет значения, поскольку во многих примерах это не работает, даже в небольших, всего в 10 символов. Попробуйте NGmGafjTwr
Проблема исправлена. Логично, что нет никакой разницы между моим решением и решением вопроса. Поэтому они должны иметь одинаковый результат для каждого тестового примера.
Вы пробовали использовать предоставленный тестовый пример? Похоже, вы сначала добавите строчную букву.