【问题标题】:How to sort a array that contains special characters alphabetically?如何按字母顺序对包含特殊字符的数组进行排序?
【发布时间】:2021-10-28 09:40:09
【问题描述】:

我正在寻找根据某种格式准备的以下字符串在标准输出中产生以下输出的代码。

假设和规则:

  • 每个字母在给定字符串中使用 2 次,并且相同 2 个字母之间的字母将被视为 个字母。
  • 给定的字符串总是以正确的格式给出。字符串格式 不需要检查。

示例:

输入abccbdeeda

预期输出

a
--b
----c
--d
----e

解释:因为两个字母“b”出现在字母“a”之间,所以字母b需要两个连字符(--b

尝试

public static void main(String[] args) {
    String input = "abccbdeeda";
    System.out.println("input: " + input);
    String[] strSplit = input.split("");
    String g = "";
    String h = "-";

    ArrayList<String> list = new ArrayList<String>();
    int counter = 1;
    boolean secondNumber;
    list.add(strSplit[0]);
    int dual = 0;
    for (int i = 1; i < strSplit.length; i++) {
        secondNumber = list.contains(strSplit[i]);
        if ((secondNumber)) {
            counter--;
            dual = counter * 2;
            for (int f = 0; f < dual; f++) {
                strSplit[i] = h.concat(strSplit[i]);
            }
            g = "";
            dual = 0;
        } else {
            list.add(strSplit[i]);
            counter++;
        }
    }
    Arrays.sort(strSplit);
    for (int p = 0; p < strSplit.length; p++) {
        System.out.println(strSplit[p]);
    }
}

输入: abccbdeeda

我的输出:

----c 
----e 
--b 
--d 
a 

我无法按字母顺序对输出进行排序。如何使用其中的连字符按字母顺序排序?

【问题讨论】:

  • 能详细解释一下输入输出吗?
  • 您能解释一下要求如何规定输出必须按字母顺序排列吗? “fbccbdeedf”的正确输出是什么?为什么?
  • 输出:--b ----c --d ----e f.输出将是这样的。 @StephenC​​pan>
  • 1) 没有数字。只有字母。 2)这没有说明输出的顺序。要么您误解了说明……要么您没有在问题中完整准确地说明它们。
  • 或者换一种说法,为什么“f --b ----c --d ----e”也不是正确答案?

标签: java algorithm sorting


【解决方案1】:

这个任务在堆栈的帮助下很好地完成了。如果当前字符等于栈顶,那么该字符是关闭的,可以被移除,否则我们第一次遇到它,必须将它添加到堆栈和结果字符串之前添加stack.size() * 2破折号。

当我们完全遍历字符串后,我们可以对结果字符串进行排序。

public static void main(String[] args) {
    Stack<Character> stack = new Stack<>();
    String string = "abccbdeeda";
    StringBuilder result = new StringBuilder();
    for(int i = 0; i < string.length(); i++) {
        char curChar = string.charAt(i);
        if(!stack.isEmpty() && curChar == stack.peek()) {
            stack.pop();
        } else {
            result.append("-".repeat(stack.size() * 2)).append(curChar).append(" ");
            stack.add(curChar);
        }
    }

    System.out.println(result);
    System.out.println(Arrays.toString(Arrays.stream(result.toString().split(" ")).sorted().toArray()));
}

输出

a --b ----c --d ----e 
[----c, ----e, --b, --d, a]

【讨论】:

  • 非常感谢您的帮助。
【解决方案2】:

您可以遍历 strSplit 数组并将每个元素中的字符提取到单独的列表/数组中。要检查数组元素是否包含字母,您可以编写正则表达式。 例如:private final Pattern x = Pattern.compile("[a-z]");

编写一个单独的方法来匹配模式到 strSplit 数组中的每个元素。此方法将返回输入字符串中的字符。

private String findCharactor(final StringBuilder element) {
        final Matcher matcher = x.matcher(element);
        if (matcher.find()) {
            final int matchIndex = matcher.start(); //this gives the index of the char in the string
            return element.substring(matchIndex); 
        }
}

将这些返回的字符添加到单独的数组中,并使用排序函数对其进行排序。

【讨论】:

  • 是的......但是虽然这回答了所提出的问题......我很确定更好的问题解决方案不需要排序。
【解决方案3】:

假设你的结果列表是:

List<String> resultList = Arrays.asList("----c", "----e", "--b", "--d", "a");

您可以按字母顺序对它进行排序:

Collections.sort(resultList, (o1, o2) -> new StringBuilder(o1).reverse().toString().compareTo(new StringBuilder(o2).reverse().toString()));

【讨论】:

  • 非常感谢您的帮助。
【解决方案4】:

您可以将递归用于深度优先遍历(前序):

public static String dfs(String string, String prefix) {
    if (string.length() == 0) return "";
    int i = string.indexOf(string.charAt(0), 1);
    return prefix + string.charAt(0) + "\n"             // current
           + dfs(string.substring(1, i), prefix + "--") // all nested
           + dfs(string.substring(i + 1), prefix);      // all siblings
}

调用示例:

public static void main(String[] args) {
    System.out.println(dfs("abccbdeeda", ""));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多