Java 某个正整数的数字根定义为其所有数字之和

Java 某个正整数的数字根定义为其所有数字之和,java,Java,我试图在一个在线挑战网站上解决这个挑战,我有点卡住了。下面是关于这个问题的更多信息: 您将获得一个整数数组。按如下方式排序:如果a在b之前,则a的数字根小于或等于b的数字根。如果两个数字具有相同的数字根,则较小的数字(在常规意义上)应排在第一位。例如,4和13具有相同的数字根,但是4

我试图在一个在线挑战网站上解决这个挑战,我有点卡住了。下面是关于这个问题的更多信息:

您将获得一个整数数组。按如下方式排序:如果a在b之前,则a的数字根小于或等于b的数字根。如果两个数字具有相同的数字根,则较小的数字(在常规意义上)应排在第一位。例如,4和13具有相同的数字根,但是4<13,因此在任何数字根排序中,如果两者都存在,则4位于13之前

以下是我的输出:

Input: a: [13, 20, 7, 4]
Output: [20, 13, 4, 7]
Expected Output: [20, 4, 13, 7]
这是我的密码:

int digitRoot(int b) {
    int c, sum = 0;
    while(b>0) {
        c=b%10;
        sum=sum+c;
        b=b/10;
    }
    return sum;
}

int[] digitRootSort(int[] a) {
    HashMap<Integer, ArrayList<Integer>> map = new HashMap<Integer, ArrayList<Integer>>();
    int[] a1 = new int[a.length];
    for (int i=0;i<a.length;i++) {
        a1[i]=digitRoot(a[i]);
        if (map.containsKey(a1[i])) {
            ArrayList<Integer> temp = map.get(a1[i]);
            temp.add(a[i]);
            map.put(a1[i], temp);
        }
        else { 
            ArrayList<Integer> list = new ArrayList<Integer>();
            list.add(a[i]);
            map.put(a1[i], list);
        }
    }
    Arrays.sort(a1);
    for (int i=0;i<a.length;i++) {
        ArrayList<Integer> temp = map.get(a1[i]);
        for(int j=0;j<temp.size();j++) {
            a[i]=temp.get(j);
            if (j<temp.size()-1)
                i++;
        }
    }
    return a;
}

您似乎试图插入集合的排序值
Collections.sort(List)
,不管是好是坏,都会对该列表进行排序,并且不返回任何内容。首先对列表进行排序,然后将其插入地图。

看来你把事情复杂化了。编写一个实现排序规则的
比较器
,然后简单地对值进行排序

由于无法使用
比较器对
int[]
进行排序,因此首先必须对值进行装箱,否则很容易,尤其是使用Java 8+流

static int[] digitRootSort(int... values) {
    return IntStream.of(values).boxed()
                    .sorted(new DigitRootComparator())
                    .mapToInt(Integer::intValue).toArray();
}

static final class DigitRootComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer a, Integer b) {
        int cmp = Integer.compare(digitRoot(a), digitRoot(b));
        return (cmp != 0 ? cmp : Integer.compare(a, b));
    }
    private static int digitRoot(int value) {
        int sum = 0;
        for (int remain = value; remain > 0; remain /= 10)
            sum += remain % 10;
        return sum;
    }
}
输出

[20,4,13,7]

在放入地图时,不需要对数组进行排序。相反,您可以在最后一个循环中检索时对其进行排序:

    Arrays.sort(a1);
    for (int i=0;i<a.length;i++) {
        ArrayList<Integer> temp = map.get(a1[i]);
        Collections.sort(temp);
        for(int j=0;j<temp.size();j++) {
            a[i]=temp.get(j);
            if (j<temp.size()-1)
                i++;
        }
    }
Arrays.sort(a1);

对于(int i=0;i只需在最后一个for循环中包含这一个
Collections.sort(temp);
,这是必要的,因为多个数字可以具有相同的数字根,并且应该放在已排序的列表中

for (int i=0;i<a.length;i++) {
        ArrayList<Integer> temp = map.get(a1[i]);
        Collections.sort(temp);
        for(int j=0;j<temp.size();j++) {
            a[i]=temp.get(j);
            if (j<temp.size()-1)
                i++;
        }
    }
编辑:关于错误


因为在
put(a1[i],Collections.sort(list))
中,put方法需要
put(int,list)
,但是您给它
put(int,void)
,因为
Collections.sort()
的返回类型是
void
,您只需首先对列表进行排序,然后传递Collections.sort(list)返回void,其中与map中一样,您需要放置具有类型的内容。这可能有助于您执行此操作:Collections.sort(list);map.put(a1[i],list);它至少不会给您带来错误。@ssn,要更正代码,您只需在最后一个for循环(即
Collections.sort(temp);
)对
temp
列表进行排序即可。查看我的答案,甚至将其更改为Collections.sort(list);map.put(a1[i],list);给了我描述中提到的错误答案。谢谢,这是有效的。但是当我尝试在将列表放入hashmap之前对其进行排序时,它不起作用。知道为什么吗?因为在
put(a1[i],Collections.sort(list))中
put方法应为
put(int,List)
,但您提供的是
put(int,void)
,因为
Collections.sort()的返回类型
void
,您只需首先对列表进行排序,然后在put没有给我正确答案之前通过7次排序。@ssn对我来说,它是双向给出正确答案。putting
Collections.sort(temp)
在第一个循环或第二个循环中,您知道为什么在将其放入映射之前尝试对其进行排序不起作用吗?我尝试了,但没有。如果我进行集合,则不会对值进行排序。在放入之前进行排序。您需要在其他部分中执行此操作,即:map.put(a1[I],list)之前;在if部分中,排序没有任何用处,因为它只包含一个元素。
    Arrays.sort(a1);
    for (int i=0;i<a.length;i++) {
        ArrayList<Integer> temp = map.get(a1[i]);
        Collections.sort(temp);
        for(int j=0;j<temp.size();j++) {
            a[i]=temp.get(j);
            if (j<temp.size()-1)
                i++;
        }
    }
int[] digitRootSort(int[] a) {
    HashMap<Integer, TreeSet<Integer>> map = new HashMap<Integer, TreeSet<Integer>>();
    int[] a1 = new int[a.length];
    for (int i = 0; i < a.length; i++) {
        a1[i] = digitRoot(a[i]);
        if (map.containsKey(a1[i])) {
            TreeSet<Integer> set = map.get(a1[i]);
            set.add(a[i]);
            map.put(a1[i], set);
        } else {
            TreeSet<Integer> set = new TreeSet<Integer>();
            set.add(a[i]);
            map.put(a1[i], set);
        }
    }
    Arrays.sort(a1);
    for (int i = 0; i < a.length;) {
        TreeSet<Integer> set = map.get(a1[i]);
        for (int j : set) {
            a[i] = j;
            i++;
        }
    }
    return a;
}
int[] digitRootSort(int[] a) {
    SortedSet<Integer> set = new TreeSet<Integer>(new Comparator<Integer>() {

        @Override
        public int compare(Integer a, Integer b) {
            int result = Integer.compare(digitRoot(a), digitRoot(b));
            result = result == 0 ? Integer.compare(a, b) : result;
            return result;
        }
    });

    for (int i : a) {
        set.add(i);
    }

    int i = 0;
    for (int j : set) {
        a[i++] = j;
    }

    return a;
}
for (int i=0;i<a.length;i++) {
        ArrayList<Integer> temp = map.get(a1[i]);
        Collections.sort(temp);
        for(int j=0;j<temp.size();j++) {
            a[i]=temp.get(j);
            if (j<temp.size()-1)
                i++;
        }
    }
Input: a: [13, 20, 7, 4]
Output: [20, 4, 13, 7]