Java 对混合整数和字符串的数组列表进行排序,同时保留字符串和整数的相对顺序

Java 对混合整数和字符串的数组列表进行排序,同时保留字符串和整数的相对顺序,java,algorithm,sorting,arraylist,Java,Algorithm,Sorting,Arraylist,考虑如下所示的arraylist unsortedList = {6,"ball",3,1,"apple","cat",4} 这需要进行分类 sortedList = {1,"apple",3,4,"ball","cat",6} 按字母顺序对字符串排序。按升序对数字进行排序。但请注意以下条件: 无论未排序列表中的哪个整数,它都必须是已排序列表中的整数 无论未排序列表中的哪个字符串,它都必须是已排序列表中的字符串 请注意,在上面的示例中,所有整数均按升序排序,所有字符串均按升序排序,但整

考虑如下所示的arraylist

unsortedList = {6,"ball",3,1,"apple","cat",4} 
这需要进行分类

sortedList = {1,"apple",3,4,"ball","cat",6}
按字母顺序对字符串排序。按升序对数字进行排序。但请注意以下条件:

  • 无论未排序列表中的哪个整数,它都必须是已排序列表中的整数
  • 无论未排序列表中的哪个字符串,它都必须是已排序列表中的字符串

请注意,在上面的示例中,所有整数均按升序排序,所有字符串均按升序排序,但整数和字符串的相对位置与之前相同。

这里的一个选项是执行以下操作:

  • 创建原始列表中所有整数的新列表
  • 创建原始列表中所有字符串的新列表
  • 对每个列表进行排序
  • 迭代原始列表,执行以下操作:
    • 如果元素中有一个整数,则从排序整数列表中写回下一个未写入的整数
    • 如果元素中有字符串,则从排序字符串列表中写回下一个未写入的字符串
这是相当有效的-您只需要做两种排序。下面是一些代码:

public void relativeOrderSort(List<Object> list) {
    /* Create a list of just the integers and just the strings
     * from the original list.
     */
    List<Integer> intList = new ArrayList<Integer>();
    List<String> strList = new ArrayList<String>();
    for (Object obj: list) {
        if (obj instanceof Integer) {
            intList.add((Integer) obj);
        } else if (obj instanceof String) {
            strList.add((String) obj);
        } else {
            throw new IllegalArgumentException("List has a non-int, non-string member.");
        }
    }

    /* Sort the lists. */
    Collections.sort(intList);
    Collections.sort(strList);

    /* Merge the lists back together. */
    int intIndex = 0, strIndex = 0;
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i) instanceof Integer) {
           list.set(i, intList.get(intIndex++));
        } else {
           list.set(i, strList.get(strIndex++));
        }
    }
}
public void relativeOrderSort(列表){
/*创建一个只包含整数和字符串的列表
*从原始列表中删除。
*/
List intList=new ArrayList();
List strList=new ArrayList();
对于(对象对象:列表){
if(obj instanceof Integer){
intList.add((整数)obj);
}else if(字符串的obj实例){
strList.add((字符串)obj);
}否则{
抛出新的IllegalArgumentException(“列表有一个非int、非字符串的成员。”);
}
}
/*对列表进行排序*/
Collections.sort(intList);
Collections.sort(strList);
/*将列表重新合并在一起*/
int intIndex=0,strIndex=0;
对于(int i=0;i
希望这有帮助

伪代码:

Create a list of the indices pointing to integers ({0,2,3,6} in your case - indxInt )
Sort the integers  ({6,3,1,4} turns into {1,3,4,6})
Put them back at the locations given by the pointers:
  sorted(indxInt(0)) = 1;
  sorted(indxInt(1)) = 3;
  sorted(3) = 4; // indxInt(2) == 3
  sorted(6) = 6; // indxInt(3) == 6
Repeat for the strings

我很难弄清楚分类标准。是什么让“苹果”>1和“球”>4?@jterrace一文不值。他只是想让整数保持在未排序列表中的相同位置(与字符串相同)。然后对整数与整数、字符串与字符串进行排序。建议:将其拆分为整数/字符串列表,对它们进行排序,然后根据原始列表中的类型将它们重新组合到新列表中(
LinkedList#poll
很好)。我明白了。。。必须保留数据类型顺序。完美。在合并已排序的列表时,我丢失了对原始列表的引用。对于diff,输入/输出应为数组的相同解决方案被采访者称为“不优雅”。我想知道有谁知道“优雅”的吗?我会回答我的问题。。。。可以使用修改后的合并排序。在这种情况下,您将不需要额外的N空间。@AliakseiYatsau传统的合并排序实现使用线性辅助存储空间来保存合并期间的元素。从复杂性的角度来看,这会增加什么新东西吗?@templatetypedef我不知道它在现实世界中是如何实现的。我有一个主意。这不是一个合适的合并想法,但至少在面试时可以做的事情是使用辅助存储,但当它是全移位数组时,它会更小。Alg复杂性仍将是NlogN,但它将增加额外的处理(移位)。我不认为它比原版更“优雅”,但说实话,我已经没有“优雅”的想法了。。。